n2words 5.0.0 → 5.1.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/CHANGELOG.md +128 -42
- package/README.md +6 -4
- package/dist/am-ET.js +2 -2
- package/dist/am-ET.umd.js +2 -2
- package/dist/am-Latn-ET.js +2 -2
- package/dist/am-Latn-ET.umd.js +2 -2
- package/dist/ar-SA.js +2 -2
- package/dist/ar-SA.umd.js +2 -2
- package/dist/az-AZ.js +2 -2
- package/dist/az-AZ.umd.js +2 -2
- package/dist/bn-BD.js +2 -2
- package/dist/bn-BD.umd.js +2 -2
- package/dist/cs-CZ.js +2 -2
- package/dist/cs-CZ.umd.js +2 -2
- package/dist/da-DK.js +2 -2
- package/dist/da-DK.umd.js +2 -2
- package/dist/de-DE.js +2 -2
- package/dist/de-DE.umd.js +2 -2
- package/dist/el-GR.js +2 -2
- package/dist/el-GR.umd.js +2 -2
- package/dist/en-AU.js +2 -2
- package/dist/en-AU.umd.js +2 -2
- package/dist/en-BD.js +2 -2
- package/dist/en-BD.umd.js +2 -2
- package/dist/en-CA.js +2 -2
- package/dist/en-CA.umd.js +2 -2
- package/dist/en-GB.js +2 -2
- package/dist/en-GB.umd.js +2 -2
- package/dist/en-GH.js +2 -2
- package/dist/en-GH.umd.js +2 -2
- package/dist/en-IE.js +2 -2
- package/dist/en-IE.umd.js +2 -2
- package/dist/en-IN.js +2 -2
- package/dist/en-IN.umd.js +2 -2
- package/dist/en-KE.js +2 -2
- package/dist/en-KE.umd.js +2 -2
- package/dist/en-MY.js +2 -2
- package/dist/en-MY.umd.js +2 -2
- package/dist/en-NG.js +2 -2
- package/dist/en-NG.umd.js +2 -2
- package/dist/en-NZ.js +2 -2
- package/dist/en-NZ.umd.js +2 -2
- package/dist/en-PH.js +2 -2
- package/dist/en-PH.umd.js +2 -2
- package/dist/en-PK.js +2 -2
- package/dist/en-PK.umd.js +2 -2
- package/dist/en-SG.js +2 -2
- package/dist/en-SG.umd.js +2 -2
- package/dist/en-US.js +2 -2
- package/dist/en-US.umd.js +2 -2
- package/dist/en-ZA.js +2 -2
- package/dist/en-ZA.umd.js +2 -2
- package/dist/es-ES.js +2 -2
- package/dist/es-ES.umd.js +2 -2
- package/dist/es-MX.js +2 -2
- package/dist/es-MX.umd.js +2 -2
- package/dist/es-US.js +2 -2
- package/dist/es-US.umd.js +2 -2
- package/dist/fa-IR.js +2 -2
- package/dist/fa-IR.umd.js +2 -2
- package/dist/fi-FI.js +2 -2
- package/dist/fi-FI.umd.js +2 -2
- package/dist/fil-PH.js +2 -2
- package/dist/fil-PH.umd.js +2 -2
- package/dist/fr-BE.js +2 -2
- package/dist/fr-BE.umd.js +2 -2
- package/dist/fr-FR.js +2 -2
- package/dist/fr-FR.umd.js +2 -2
- package/dist/gu-IN.js +2 -2
- package/dist/gu-IN.umd.js +2 -2
- package/dist/ha-NG.js +2 -2
- package/dist/ha-NG.umd.js +2 -2
- package/dist/hbo-IL.js +2 -2
- package/dist/hbo-IL.umd.js +2 -2
- package/dist/he-IL.js +2 -2
- package/dist/he-IL.umd.js +2 -2
- package/dist/hi-IN.js +2 -2
- package/dist/hi-IN.umd.js +2 -2
- package/dist/hr-HR.js +2 -2
- package/dist/hr-HR.umd.js +2 -2
- package/dist/hu-HU.js +2 -2
- package/dist/hu-HU.umd.js +2 -2
- package/dist/id-ID.js +2 -2
- package/dist/id-ID.umd.js +2 -2
- package/dist/it-IT.js +2 -2
- package/dist/it-IT.umd.js +2 -2
- package/dist/ja-JP.js +2 -2
- package/dist/ja-JP.umd.js +2 -2
- package/dist/ka-GE.js +2 -2
- package/dist/ka-GE.umd.js +2 -2
- package/dist/kn-IN.js +2 -2
- package/dist/kn-IN.umd.js +2 -2
- package/dist/ko-KR.js +2 -2
- package/dist/ko-KR.umd.js +2 -2
- package/dist/lt-LT.js +2 -2
- package/dist/lt-LT.umd.js +2 -2
- package/dist/lv-LV.js +2 -2
- package/dist/lv-LV.umd.js +2 -2
- package/dist/mr-IN.js +2 -2
- package/dist/mr-IN.umd.js +2 -2
- package/dist/ms-MY.js +2 -2
- package/dist/ms-MY.umd.js +2 -2
- package/dist/nb-NO.js +2 -2
- package/dist/nb-NO.umd.js +2 -2
- package/dist/nl-NL.js +2 -2
- package/dist/nl-NL.umd.js +2 -2
- package/dist/pa-IN.js +2 -2
- package/dist/pa-IN.umd.js +2 -2
- package/dist/pl-PL.js +2 -2
- package/dist/pl-PL.umd.js +2 -2
- package/dist/pt-BR.js +2 -2
- package/dist/pt-BR.umd.js +2 -2
- package/dist/pt-PT.js +2 -2
- package/dist/pt-PT.umd.js +2 -2
- package/dist/ro-RO.js +2 -2
- package/dist/ro-RO.umd.js +2 -2
- package/dist/ru-RU.js +2 -2
- package/dist/ru-RU.umd.js +2 -2
- package/dist/sr-Cyrl-RS.js +2 -2
- package/dist/sr-Cyrl-RS.umd.js +2 -2
- package/dist/sr-Latn-RS.js +2 -2
- package/dist/sr-Latn-RS.umd.js +2 -2
- package/dist/sv-SE.js +2 -2
- package/dist/sv-SE.umd.js +2 -2
- package/dist/sw-KE.js +2 -2
- package/dist/sw-KE.umd.js +2 -2
- package/dist/ta-IN.js +2 -2
- package/dist/ta-IN.umd.js +2 -2
- package/dist/te-IN.js +2 -2
- package/dist/te-IN.umd.js +2 -2
- package/dist/th-TH.js +2 -2
- package/dist/th-TH.umd.js +2 -2
- package/dist/tr-TR.js +2 -2
- package/dist/tr-TR.umd.js +2 -2
- package/dist/uk-UA.js +2 -2
- package/dist/uk-UA.umd.js +2 -2
- package/dist/ur-PK.js +2 -2
- package/dist/ur-PK.umd.js +2 -2
- package/dist/vi-VN.js +2 -2
- package/dist/vi-VN.umd.js +2 -2
- package/dist/yo-NG.js +2 -2
- package/dist/yo-NG.umd.js +2 -2
- package/dist/zh-Hans-CN.js +2 -2
- package/dist/zh-Hans-CN.umd.js +2 -2
- package/dist/zh-Hant-TW.js +2 -2
- package/dist/zh-Hant-TW.umd.js +2 -2
- package/package.json +31 -22
- package/src/am-ET.d.ts +3 -5
- package/src/am-ET.js +41 -16
- package/src/am-Latn-ET.d.ts +3 -5
- package/src/am-Latn-ET.js +45 -16
- package/src/ar-SA.d.ts +44 -18
- package/src/ar-SA.js +93 -40
- package/src/az-AZ.d.ts +3 -5
- package/src/az-AZ.js +58 -20
- package/src/bn-BD.d.ts +3 -5
- package/src/bn-BD.js +32 -16
- package/src/cs-CZ.d.ts +3 -6
- package/src/cs-CZ.js +66 -42
- package/src/da-DK.d.ts +3 -6
- package/src/da-DK.js +53 -48
- package/src/de-DE.d.ts +17 -11
- package/src/de-DE.js +88 -57
- package/src/el-GR.d.ts +3 -6
- package/src/el-GR.js +45 -32
- package/src/en-AU.d.ts +17 -11
- package/src/en-AU.js +56 -41
- package/src/en-BD.d.ts +17 -11
- package/src/en-BD.js +60 -41
- package/src/en-CA.d.ts +36 -18
- package/src/en-CA.js +67 -46
- package/src/en-GB.d.ts +17 -11
- package/src/en-GB.js +56 -41
- package/src/en-GH.d.ts +32 -3
- package/src/en-GH.js +104 -26
- package/src/en-IE.d.ts +17 -11
- package/src/en-IE.js +56 -41
- package/src/en-IN.d.ts +17 -11
- package/src/en-IN.js +60 -41
- package/src/en-KE.d.ts +28 -3
- package/src/en-KE.js +93 -26
- package/src/en-MY.d.ts +26 -3
- package/src/en-MY.js +91 -26
- package/src/en-NG.d.ts +17 -11
- package/src/en-NG.js +56 -41
- package/src/en-NZ.d.ts +32 -3
- package/src/en-NZ.js +85 -31
- package/src/en-PH.d.ts +32 -3
- package/src/en-PH.js +97 -26
- package/src/en-PK.d.ts +17 -11
- package/src/en-PK.js +60 -41
- package/src/en-SG.d.ts +28 -3
- package/src/en-SG.js +93 -26
- package/src/en-US.d.ts +36 -18
- package/src/en-US.js +70 -47
- package/src/en-ZA.d.ts +17 -11
- package/src/en-ZA.js +56 -41
- package/src/es-ES.d.ts +53 -21
- package/src/es-ES.js +104 -56
- package/src/es-MX.d.ts +53 -21
- package/src/es-MX.js +104 -56
- package/src/es-US.d.ts +53 -21
- package/src/es-US.js +92 -51
- package/src/fa-IR.d.ts +3 -5
- package/src/fa-IR.js +28 -13
- package/src/fi-FI.d.ts +3 -6
- package/src/fi-FI.js +47 -29
- package/src/fil-PH.d.ts +3 -5
- package/src/fil-PH.js +61 -28
- package/src/fr-BE.d.ts +31 -15
- package/src/fr-BE.js +128 -57
- package/src/fr-FR.d.ts +31 -16
- package/src/fr-FR.js +97 -60
- package/src/gu-IN.d.ts +3 -5
- package/src/gu-IN.js +31 -16
- package/src/ha-NG.d.ts +3 -5
- package/src/ha-NG.js +55 -27
- package/src/hbo-IL.d.ts +26 -12
- package/src/hbo-IL.js +92 -51
- package/src/he-IL.d.ts +17 -10
- package/src/he-IL.js +92 -50
- package/src/hi-IN.d.ts +3 -5
- package/src/hi-IN.js +30 -17
- package/src/hr-HR.d.ts +21 -10
- package/src/hr-HR.js +89 -33
- package/src/hu-HU.d.ts +3 -5
- package/src/hu-HU.js +57 -23
- package/src/id-ID.d.ts +3 -5
- package/src/id-ID.js +56 -23
- package/src/it-IT.d.ts +17 -11
- package/src/it-IT.js +74 -43
- package/src/ja-JP.d.ts +3 -6
- package/src/ja-JP.js +39 -26
- package/src/ka-GE.d.ts +3 -6
- package/src/ka-GE.js +38 -26
- package/src/kn-IN.d.ts +3 -5
- package/src/kn-IN.js +31 -16
- package/src/ko-KR.d.ts +3 -6
- package/src/ko-KR.js +34 -26
- package/src/lt-LT.d.ts +21 -11
- package/src/lt-LT.js +64 -42
- package/src/lv-LV.d.ts +21 -11
- package/src/lv-LV.js +79 -51
- package/src/mr-IN.d.ts +3 -5
- package/src/mr-IN.js +31 -16
- package/src/ms-MY.d.ts +3 -5
- package/src/ms-MY.js +58 -24
- package/src/nb-NO.d.ts +3 -6
- package/src/nb-NO.js +54 -34
- package/src/nl-NL.d.ts +41 -20
- package/src/nl-NL.js +111 -69
- package/src/pa-IN.d.ts +3 -5
- package/src/pa-IN.js +32 -16
- package/src/pl-PL.d.ts +21 -11
- package/src/pl-PL.js +69 -45
- package/src/pt-BR.d.ts +22 -11
- package/src/pt-BR.js +93 -53
- package/src/pt-PT.d.ts +17 -11
- package/src/pt-PT.js +80 -48
- package/src/ro-RO.d.ts +21 -11
- package/src/ro-RO.js +77 -39
- package/src/ru-RU.d.ts +35 -15
- package/src/ru-RU.js +100 -38
- package/src/sr-Cyrl-RS.d.ts +35 -15
- package/src/sr-Cyrl-RS.js +100 -38
- package/src/sr-Latn-RS.d.ts +35 -15
- package/src/sr-Latn-RS.js +100 -38
- package/src/sv-SE.d.ts +3 -6
- package/src/sv-SE.js +53 -34
- package/src/sw-KE.d.ts +3 -5
- package/src/sw-KE.js +50 -20
- package/src/ta-IN.d.ts +3 -5
- package/src/ta-IN.js +29 -17
- package/src/te-IN.d.ts +3 -5
- package/src/te-IN.js +31 -16
- package/src/th-TH.d.ts +3 -5
- package/src/th-TH.js +42 -19
- package/src/tr-TR.d.ts +17 -11
- package/src/tr-TR.js +63 -37
- package/src/uk-UA.d.ts +21 -10
- package/src/uk-UA.js +89 -33
- package/src/ur-PK.d.ts +3 -5
- package/src/ur-PK.js +32 -16
- package/src/utils/check-max.d.ts +26 -0
- package/src/utils/check-max.js +33 -0
- package/src/utils/expand-scientific.d.ts +0 -4
- package/src/utils/expand-scientific.js +7 -9
- package/src/utils/is-plain-object.d.ts +3 -4
- package/src/utils/is-plain-object.js +3 -4
- package/src/utils/parse-cardinal.d.ts +1 -2
- package/src/utils/parse-cardinal.js +12 -9
- package/src/utils/parse-currency.d.ts +1 -2
- package/src/utils/parse-currency.js +9 -11
- package/src/utils/parse-ordinal.d.ts +0 -1
- package/src/utils/parse-ordinal.js +9 -10
- package/src/utils/resolve-options.d.ts +17 -0
- package/src/utils/resolve-options.js +56 -0
- package/src/utils/scale.d.ts +49 -0
- package/src/utils/scale.js +65 -0
- package/src/vi-VN.d.ts +3 -6
- package/src/vi-VN.js +41 -28
- package/src/yo-NG.d.ts +3 -5
- package/src/yo-NG.js +49 -33
- package/src/zh-Hans-CN.d.ts +45 -20
- package/src/zh-Hans-CN.js +84 -31
- package/src/zh-Hant-TW.d.ts +45 -20
- package/src/zh-Hant-TW.js +85 -34
- package/src/utils/validate-options.d.ts +0 -8
- package/src/utils/validate-options.js +0 -16
package/src/da-DK.js
CHANGED
|
@@ -14,6 +14,8 @@
|
|
|
14
14
|
import { parseCardinalValue } from './utils/parse-cardinal.js'
|
|
15
15
|
import { parseCurrencyValue } from './utils/parse-currency.js'
|
|
16
16
|
import { parseOrdinalValue } from './utils/parse-ordinal.js'
|
|
17
|
+
import { checkMax } from './utils/check-max.js'
|
|
18
|
+
import { western } from './utils/scale.js'
|
|
17
19
|
|
|
18
20
|
// ============================================================================
|
|
19
21
|
// Vocabulary (module-level constants)
|
|
@@ -38,12 +40,21 @@ const DECIMAL_SEP = 'komma'
|
|
|
38
40
|
// Long scale: millioner, millarder, billioner, etc.
|
|
39
41
|
const SCALES = ['millioner', 'millarder', 'billioner', 'billarder', 'trillioner', 'trillarder', 'quadrillioner', 'quadrillarder']
|
|
40
42
|
|
|
43
|
+
// Supported magnitude ceiling (checked at the public entry points). Segments
|
|
44
|
+
// are [units, thousands, then one per SCALES entry], so cardinals span at most
|
|
45
|
+
// SCALES.length + 2 groups of 3 digits — they must stay below 10^30. Ordinals
|
|
46
|
+
// and currency build on the cardinal, so they share the same ceiling.
|
|
47
|
+
export const cardinalMax = western(SCALES.length + 1)
|
|
48
|
+
export const ordinalMax = western(SCALES.length + 1)
|
|
49
|
+
export const currencyMax = western(SCALES.length + 1)
|
|
50
|
+
|
|
41
51
|
// ============================================================================
|
|
42
52
|
// Ordinal Vocabulary
|
|
43
53
|
// ============================================================================
|
|
44
54
|
|
|
45
55
|
// Danish ordinals: 1st-2nd special, others use -te/-nde suffix
|
|
46
56
|
// "anden/andet" for 2nd (common/neuter), we use common form
|
|
57
|
+
/** @type {Record<number, string>} */
|
|
47
58
|
const ORDINAL_SPECIAL = {
|
|
48
59
|
1: 'første',
|
|
49
60
|
2: 'anden',
|
|
@@ -56,7 +67,7 @@ const ORDINAL_SPECIAL = {
|
|
|
56
67
|
9: 'niende',
|
|
57
68
|
10: 'tiende',
|
|
58
69
|
11: 'ellevte',
|
|
59
|
-
12: 'tolvte'
|
|
70
|
+
12: 'tolvte',
|
|
60
71
|
}
|
|
61
72
|
|
|
62
73
|
// ============================================================================
|
|
@@ -73,8 +84,10 @@ const ORE = 'øre' // same singular and plural
|
|
|
73
84
|
|
|
74
85
|
/**
|
|
75
86
|
* Builds segment word for 0-999.
|
|
87
|
+
* @param {number} n - Integer in range 0-999
|
|
88
|
+
* @returns {string} Danish words for the segment
|
|
76
89
|
*/
|
|
77
|
-
function buildSegment
|
|
90
|
+
function buildSegment(n) {
|
|
78
91
|
if (n === 0) return ''
|
|
79
92
|
|
|
80
93
|
const ones = n % 10
|
|
@@ -93,16 +106,20 @@ function buildSegment (n) {
|
|
|
93
106
|
|
|
94
107
|
if (tensOnes === 0) {
|
|
95
108
|
// Just hundreds
|
|
96
|
-
}
|
|
109
|
+
}
|
|
110
|
+
else if (tensOnes < 10) {
|
|
97
111
|
// Single digit
|
|
98
112
|
parts.push(ONES[ones])
|
|
99
|
-
}
|
|
113
|
+
}
|
|
114
|
+
else if (tensOnes < 20) {
|
|
100
115
|
// Teens
|
|
101
116
|
parts.push(TEENS[ones])
|
|
102
|
-
}
|
|
117
|
+
}
|
|
118
|
+
else if (ones === 0) {
|
|
103
119
|
// Even tens
|
|
104
120
|
parts.push(TENS[tens])
|
|
105
|
-
}
|
|
121
|
+
}
|
|
122
|
+
else {
|
|
106
123
|
// Units-before-tens: "enogtyve", "treogfyrre"
|
|
107
124
|
parts.push(ONES_VIGESIMAL[ones] + 'og' + TENS[tens])
|
|
108
125
|
}
|
|
@@ -120,11 +137,10 @@ function buildSegment (n) {
|
|
|
120
137
|
|
|
121
138
|
/**
|
|
122
139
|
* Converts a non-negative integer to Danish words.
|
|
123
|
-
*
|
|
124
140
|
* @param {bigint} n - Non-negative integer to convert
|
|
125
141
|
* @returns {string} Danish words
|
|
126
142
|
*/
|
|
127
|
-
function integerToWords
|
|
143
|
+
function integerToWords(n) {
|
|
128
144
|
if (n === 0n) return ZERO
|
|
129
145
|
|
|
130
146
|
// Fast path: numbers < 1000 (direct lookup)
|
|
@@ -154,11 +170,10 @@ function integerToWords (n) {
|
|
|
154
170
|
|
|
155
171
|
/**
|
|
156
172
|
* Builds words for numbers >= 1,000,000.
|
|
157
|
-
*
|
|
158
173
|
* @param {bigint} n - Number >= 1,000,000
|
|
159
174
|
* @returns {string} Danish words
|
|
160
175
|
*/
|
|
161
|
-
function buildLargeNumberWords
|
|
176
|
+
function buildLargeNumberWords(n) {
|
|
162
177
|
const numStr = n.toString()
|
|
163
178
|
const len = numStr.length
|
|
164
179
|
|
|
@@ -178,6 +193,7 @@ function buildLargeNumberWords (n) {
|
|
|
178
193
|
}
|
|
179
194
|
|
|
180
195
|
// Convert segments to words with scale tracking
|
|
196
|
+
// Callers guard the magnitude (cardinalMax) before reaching here.
|
|
181
197
|
// scaleIndex: 0 = units, 1 = thousands, 2 = millions, etc.
|
|
182
198
|
const parts = []
|
|
183
199
|
let scaleIndex = segments.length - 1
|
|
@@ -191,10 +207,12 @@ function buildLargeNumberWords (n) {
|
|
|
191
207
|
if (scaleIndex === 0) {
|
|
192
208
|
// Units segment
|
|
193
209
|
parts.push({ word: segmentWord, type: 'units' })
|
|
194
|
-
}
|
|
210
|
+
}
|
|
211
|
+
else if (scaleIndex === 1) {
|
|
195
212
|
// Thousands - compound form
|
|
196
213
|
parts.push({ word: segmentWord + THOUSAND, type: 'thousand' })
|
|
197
|
-
}
|
|
214
|
+
}
|
|
215
|
+
else {
|
|
198
216
|
// Millions+ - space-separated, use "en" for 1
|
|
199
217
|
const scaleWord = SCALES[scaleIndex - 2]
|
|
200
218
|
let numWord = segmentWord
|
|
@@ -217,50 +235,38 @@ function buildLargeNumberWords (n) {
|
|
|
217
235
|
* Joins parts with Danish spacing rules.
|
|
218
236
|
* - After thousands with remainder: "tusinde og"
|
|
219
237
|
* - Millions are space-separated
|
|
220
|
-
*
|
|
221
|
-
* @param {Array} parts - Parts with type metadata
|
|
238
|
+
* @param {Array<{word: string, type: string}>} parts - Parts with type metadata
|
|
222
239
|
* @returns {string} Joined string
|
|
223
240
|
*/
|
|
224
|
-
function joinDanishParts
|
|
241
|
+
function joinDanishParts(parts) {
|
|
225
242
|
if (parts.length === 0) return ZERO
|
|
226
|
-
if (parts.length === 1) return parts[0].word
|
|
227
243
|
|
|
228
|
-
const
|
|
244
|
+
const tokens = []
|
|
229
245
|
|
|
230
246
|
for (let i = 0; i < parts.length; i++) {
|
|
231
247
|
const part = parts[i]
|
|
232
248
|
const nextPart = parts[i + 1]
|
|
233
249
|
|
|
234
250
|
if (part.type === 'thousand' && nextPart && nextPart.type === 'units') {
|
|
235
|
-
// Thousands followed by units:
|
|
236
|
-
|
|
237
|
-
i++ //
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
}
|
|
242
|
-
result.push(part.word)
|
|
243
|
-
if (nextPart) {
|
|
244
|
-
result.push(' ')
|
|
245
|
-
}
|
|
246
|
-
} else {
|
|
247
|
-
if (result.length > 0 && !result[result.length - 1].endsWith(' ')) {
|
|
248
|
-
result.push(' ')
|
|
249
|
-
}
|
|
250
|
-
result.push(part.word)
|
|
251
|
+
// Thousands directly followed by the units segment: compound "…tusinde og …"
|
|
252
|
+
tokens.push(part.word + 'e og ' + nextPart.word)
|
|
253
|
+
i++ // consumed the units part
|
|
254
|
+
}
|
|
255
|
+
else {
|
|
256
|
+
tokens.push(part.word)
|
|
251
257
|
}
|
|
252
258
|
}
|
|
253
259
|
|
|
254
|
-
|
|
260
|
+
// Every remaining boundary (between scale groups) is a single space.
|
|
261
|
+
return tokens.join(' ')
|
|
255
262
|
}
|
|
256
263
|
|
|
257
264
|
/**
|
|
258
265
|
* Converts decimal digits to Danish words.
|
|
259
|
-
*
|
|
260
266
|
* @param {string} decimalPart - Decimal digits (without the point)
|
|
261
267
|
* @returns {string} Danish words for decimal part
|
|
262
268
|
*/
|
|
263
|
-
function decimalPartToWords
|
|
269
|
+
function decimalPartToWords(decimalPart) {
|
|
264
270
|
let result = ''
|
|
265
271
|
|
|
266
272
|
// Handle leading zeros
|
|
@@ -283,19 +289,20 @@ function decimalPartToWords (decimalPart) {
|
|
|
283
289
|
|
|
284
290
|
/**
|
|
285
291
|
* Converts a numeric value to Danish words.
|
|
286
|
-
*
|
|
287
292
|
* @param {number | string | bigint} value - The numeric value to convert
|
|
288
293
|
* @returns {string} The number in Danish words
|
|
289
294
|
* @throws {TypeError} If value is not a valid numeric type
|
|
290
295
|
* @throws {Error} If value is not a valid number format
|
|
291
|
-
*
|
|
292
296
|
* @example
|
|
293
297
|
* toCardinal(21) // 'enogtyve'
|
|
294
298
|
* toCardinal(1000) // 'ettusind'
|
|
295
299
|
* toCardinal(1000000) // 'en millioner'
|
|
296
300
|
*/
|
|
297
|
-
function toCardinal
|
|
301
|
+
function toCardinal(value) {
|
|
298
302
|
const { isNegative, integerPart, decimalPart } = parseCardinalValue(value)
|
|
303
|
+
// Both the integer part and the decimal's significant digits are spelled via
|
|
304
|
+
// the scale builder, so both must clear the ceiling.
|
|
305
|
+
checkMax(integerPart, cardinalMax, decimalPart)
|
|
299
306
|
|
|
300
307
|
let result = ''
|
|
301
308
|
|
|
@@ -321,11 +328,10 @@ function toCardinal (value) {
|
|
|
321
328
|
*
|
|
322
329
|
* Danish ordinals: første (1st), anden (2nd), tredje (3rd), etc.
|
|
323
330
|
* 1-12 have special forms, others use cardinal + -de/-nde suffix.
|
|
324
|
-
*
|
|
325
331
|
* @param {bigint} n - Positive integer to convert
|
|
326
332
|
* @returns {string} Danish ordinal words
|
|
327
333
|
*/
|
|
328
|
-
function integerToOrdinal
|
|
334
|
+
function integerToOrdinal(n) {
|
|
329
335
|
// Special forms for 1-12
|
|
330
336
|
if (n >= 1n && n <= 12n) {
|
|
331
337
|
return ORDINAL_SPECIAL[Number(n)]
|
|
@@ -338,19 +344,18 @@ function integerToOrdinal (n) {
|
|
|
338
344
|
|
|
339
345
|
/**
|
|
340
346
|
* Converts a numeric value to Danish ordinal words.
|
|
341
|
-
*
|
|
342
347
|
* @param {number | string | bigint} value - The numeric value to convert (positive integer)
|
|
343
348
|
* @returns {string} The number as ordinal words
|
|
344
349
|
* @throws {TypeError} If value is not a valid numeric type
|
|
345
350
|
* @throws {RangeError} If value is negative, zero, or has a decimal part
|
|
346
|
-
*
|
|
347
351
|
* @example
|
|
348
352
|
* toOrdinal(1) // 'første'
|
|
349
353
|
* toOrdinal(2) // 'anden'
|
|
350
354
|
* toOrdinal(21) // 'enogtyvede'
|
|
351
355
|
*/
|
|
352
|
-
function toOrdinal
|
|
356
|
+
function toOrdinal(value) {
|
|
353
357
|
const integerPart = parseOrdinalValue(value)
|
|
358
|
+
checkMax(integerPart, ordinalMax)
|
|
354
359
|
return integerToOrdinal(integerPart)
|
|
355
360
|
}
|
|
356
361
|
|
|
@@ -362,19 +367,18 @@ function toOrdinal (value) {
|
|
|
362
367
|
* Converts a numeric value to Danish currency words (Danish Krone).
|
|
363
368
|
*
|
|
364
369
|
* Uses krone/kroner and øre (100 øre = 1 krone).
|
|
365
|
-
*
|
|
366
370
|
* @param {number | string | bigint} value - The currency amount to convert
|
|
367
371
|
* @returns {string} The amount in Danish currency words
|
|
368
372
|
* @throws {TypeError} If value is not a valid numeric type
|
|
369
373
|
* @throws {Error} If value is not a valid number format
|
|
370
|
-
*
|
|
371
374
|
* @example
|
|
372
375
|
* toCurrency(1) // 'en krone'
|
|
373
376
|
* toCurrency(42) // 'toogfyrre kroner'
|
|
374
377
|
* toCurrency(1.50) // 'en krone og halvtreds øre'
|
|
375
378
|
*/
|
|
376
|
-
function toCurrency
|
|
379
|
+
function toCurrency(value) {
|
|
377
380
|
const { isNegative, dollars: kroner, cents: ore } = parseCurrencyValue(value)
|
|
381
|
+
checkMax(kroner, currencyMax)
|
|
378
382
|
|
|
379
383
|
let result = ''
|
|
380
384
|
if (isNegative) {
|
|
@@ -385,7 +389,8 @@ function toCurrency (value) {
|
|
|
385
389
|
if (kroner > 0n || ore === 0n) {
|
|
386
390
|
if (kroner === 1n) {
|
|
387
391
|
result += 'en ' + KRONE
|
|
388
|
-
}
|
|
392
|
+
}
|
|
393
|
+
else {
|
|
389
394
|
result += integerToWords(kroner) + ' ' + KRONER
|
|
390
395
|
}
|
|
391
396
|
}
|
package/src/de-DE.d.ts
CHANGED
|
@@ -1,14 +1,27 @@
|
|
|
1
|
+
export const cardinalMax: bigint;
|
|
2
|
+
export const ordinalMax: bigint;
|
|
3
|
+
export const currencyMax: bigint;
|
|
4
|
+
/**
|
|
5
|
+
* @typedef {object} CurrencyOptions
|
|
6
|
+
* @property {boolean} [and] - Use "und" between euros and cents
|
|
7
|
+
*/
|
|
8
|
+
/** @type {Required<CurrencyOptions>} */
|
|
9
|
+
export const currencyDefaults: Required<CurrencyOptions>;
|
|
10
|
+
export type CurrencyOptions = {
|
|
11
|
+
/**
|
|
12
|
+
* - Use "und" between euros and cents
|
|
13
|
+
*/
|
|
14
|
+
and?: boolean | undefined;
|
|
15
|
+
};
|
|
1
16
|
/**
|
|
2
17
|
* Converts a numeric value to German words.
|
|
3
18
|
*
|
|
4
19
|
* This is the main public API. It accepts any valid numeric input
|
|
5
20
|
* (number, string, or bigint) and handles parsing internally.
|
|
6
|
-
*
|
|
7
21
|
* @param {number | string | bigint} value - The numeric value to convert
|
|
8
22
|
* @returns {string} The number in German words
|
|
9
23
|
* @throws {TypeError} If value is not a valid numeric type
|
|
10
24
|
* @throws {Error} If value is not a valid number format
|
|
11
|
-
*
|
|
12
25
|
* @example
|
|
13
26
|
* toCardinal(21) // 'einundzwanzig'
|
|
14
27
|
* toCardinal(1000) // 'eintausend'
|
|
@@ -20,12 +33,10 @@ export function toCardinal(value: number | string | bigint): string;
|
|
|
20
33
|
*
|
|
21
34
|
* German ordinals add -te for 1-19 and -ste for 20+.
|
|
22
35
|
* Irregular forms: erste (1st), dritte (3rd), siebte (7th), achte (8th).
|
|
23
|
-
*
|
|
24
36
|
* @param {number | string | bigint} value - The numeric value to convert (positive integer)
|
|
25
37
|
* @returns {string} The number as ordinal words
|
|
26
38
|
* @throws {TypeError} If value is not a valid numeric type
|
|
27
39
|
* @throws {RangeError} If value is negative, zero, or has a decimal part
|
|
28
|
-
*
|
|
29
40
|
* @example
|
|
30
41
|
* toOrdinal(1) // 'erste'
|
|
31
42
|
* toOrdinal(2) // 'zweite'
|
|
@@ -37,14 +48,11 @@ export function toCardinal(value: number | string | bigint): string;
|
|
|
37
48
|
export function toOrdinal(value: number | string | bigint): string;
|
|
38
49
|
/**
|
|
39
50
|
* Converts a numeric value to German currency words (Euro).
|
|
40
|
-
*
|
|
41
51
|
* @param {number | string | bigint} value - The currency amount to convert
|
|
42
|
-
* @param {
|
|
43
|
-
* @param {boolean} [options.and=true] - Use "und" between euros and cents
|
|
52
|
+
* @param {CurrencyOptions} [options] - Optional configuration
|
|
44
53
|
* @returns {string} The amount in German currency words
|
|
45
54
|
* @throws {TypeError} If value is not a valid numeric type
|
|
46
55
|
* @throws {Error} If value is not a valid number format
|
|
47
|
-
*
|
|
48
56
|
* @example
|
|
49
57
|
* toCurrency(42.50) // 'zweiundvierzig Euro und fünfzig Cent'
|
|
50
58
|
* toCurrency(1) // 'ein Euro'
|
|
@@ -52,6 +60,4 @@ export function toOrdinal(value: number | string | bigint): string;
|
|
|
52
60
|
* toCurrency(0.01) // 'ein Cent'
|
|
53
61
|
* toCurrency(42.50, { and: false }) // 'zweiundvierzig Euro fünfzig Cent'
|
|
54
62
|
*/
|
|
55
|
-
export function toCurrency(value: number | string | bigint, options?:
|
|
56
|
-
and?: boolean | undefined;
|
|
57
|
-
}): string;
|
|
63
|
+
export function toCurrency(value: number | string | bigint, options?: CurrencyOptions): string;
|