kalpak-js 1.0.0 → 1.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/README.md +28 -32
- package/index.js +3 -213
- package/package.json +6 -3
- package/src/numbers.js +145 -0
- package/src/transliterate.js +215 -0
package/README.md
CHANGED
|
@@ -1,50 +1,46 @@
|
|
|
1
1
|
# Kalpak.js 🧢
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
Built by [**Ishipiskenler**](https://github.com/ishipiskenler) (The Doers).
|
|
3
|
+
Karakalpak language tools for JavaScript.
|
|
5
4
|
|
|
6
|
-
|
|
5
|
+
## Install
|
|
7
6
|
|
|
8
|
-
|
|
7
|
+
```bash
|
|
8
|
+
npm install kalpak-js
|
|
9
|
+
```
|
|
9
10
|
|
|
10
|
-
|
|
11
|
-
- **Cyrillic ➡️ Latin**: Supports official mappings (e.g., И→I, Ы→Í).
|
|
12
|
-
- **Zero Dependencies**: Pure JavaScript. Fast and simple.
|
|
11
|
+
## Features
|
|
13
12
|
|
|
14
|
-
|
|
13
|
+
### 1. Transliteration
|
|
15
14
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
15
|
+
Convert text between Latin and Cyrillic scripts.
|
|
16
|
+
|
|
17
|
+
```javascript
|
|
18
|
+
const { latinToCyrillic, cyrillicToLatin } = require("kalpak-js");
|
|
19
|
+
|
|
20
|
+
latinToCyrillic("Sálem"); // "Сәлем"
|
|
21
|
+
cyrillicToLatin("Сәлем"); // "Sálem"
|
|
19
22
|
```
|
|
20
23
|
|
|
21
|
-
|
|
24
|
+
### 2. Number to Text
|
|
22
25
|
|
|
23
|
-
|
|
26
|
+
Convert numbers to Karakalpak words (0 to 1 trillion).
|
|
24
27
|
|
|
25
28
|
```javascript
|
|
26
|
-
const {
|
|
29
|
+
const { numberToText } = require("kalpak-js");
|
|
27
30
|
|
|
28
|
-
//
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
// Output: "Сәлем, Қарақалпақстан!"
|
|
32
|
-
|
|
33
|
-
// 2. Cyrillic to Latin
|
|
34
|
-
const latin = cyrillicToLatin("Мен сeни жақсы көремен ❤️");
|
|
35
|
-
console.log(latin);
|
|
36
|
-
// Output: "Men seni jaqsı kóremen"
|
|
31
|
+
numberToText(42); // "qırıq eki"
|
|
32
|
+
numberToText(2026); // "eki miń jigirma altı"
|
|
33
|
+
numberToText(1000000); // "bir million"
|
|
37
34
|
```
|
|
38
35
|
|
|
39
|
-
##
|
|
40
|
-
|
|
41
|
-
We welcome contributions!
|
|
36
|
+
## API
|
|
42
37
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
38
|
+
| Function | Input | Output |
|
|
39
|
+
| ----------------------- | ----------------------- | ---------------- |
|
|
40
|
+
| `latinToCyrillic(text)` | Latin string | Cyrillic string |
|
|
41
|
+
| `cyrillicToLatin(text)` | Cyrillic string | Latin string |
|
|
42
|
+
| `numberToText(num)` | Number (0 - 1 trillion) | Karakalpak words |
|
|
47
43
|
|
|
48
|
-
|
|
44
|
+
## License
|
|
49
45
|
|
|
50
|
-
©
|
|
46
|
+
MIT © [Ishipiskenler](https://github.com/ishipiskenler)
|
package/index.js
CHANGED
|
@@ -1,218 +1,8 @@
|
|
|
1
|
-
const
|
|
2
|
-
|
|
3
|
-
A: "А",
|
|
4
|
-
a: "а",
|
|
5
|
-
B: "Б",
|
|
6
|
-
b: "б",
|
|
7
|
-
D: "Д",
|
|
8
|
-
d: "д",
|
|
9
|
-
E: "Е",
|
|
10
|
-
e: "е",
|
|
11
|
-
F: "Ф",
|
|
12
|
-
f: "ф",
|
|
13
|
-
G: "Г",
|
|
14
|
-
g: "г",
|
|
15
|
-
H: "Ҳ",
|
|
16
|
-
h: "ҳ",
|
|
17
|
-
X: "Х",
|
|
18
|
-
x: "х",
|
|
19
|
-
J: "Ж",
|
|
20
|
-
j: "ж",
|
|
21
|
-
K: "К",
|
|
22
|
-
k: "к",
|
|
23
|
-
Q: "Қ",
|
|
24
|
-
q: "қ",
|
|
25
|
-
L: "Л",
|
|
26
|
-
l: "л",
|
|
27
|
-
M: "М",
|
|
28
|
-
m: "м",
|
|
29
|
-
N: "Н",
|
|
30
|
-
n: "н",
|
|
31
|
-
O: "О",
|
|
32
|
-
o: "о",
|
|
33
|
-
P: "П",
|
|
34
|
-
p: "п",
|
|
35
|
-
R: "Р",
|
|
36
|
-
r: "р",
|
|
37
|
-
S: "С",
|
|
38
|
-
s: "с",
|
|
39
|
-
T: "Т",
|
|
40
|
-
t: "т",
|
|
41
|
-
U: "У",
|
|
42
|
-
u: "у",
|
|
43
|
-
V: "В",
|
|
44
|
-
v: "в",
|
|
45
|
-
Z: "З",
|
|
46
|
-
z: "з",
|
|
47
|
-
|
|
48
|
-
// Special Karakalpak letters
|
|
49
|
-
Á: "Ә",
|
|
50
|
-
á: "ә",
|
|
51
|
-
Ó: "Ө",
|
|
52
|
-
ó: "ө",
|
|
53
|
-
Ú: "Ү",
|
|
54
|
-
ú: "ү",
|
|
55
|
-
I: "И",
|
|
56
|
-
i: "и",
|
|
57
|
-
Í: "Ы",
|
|
58
|
-
ı: "ы",
|
|
59
|
-
Ǵ: "Ғ",
|
|
60
|
-
ǵ: "ғ",
|
|
61
|
-
Ń: "Ң",
|
|
62
|
-
ń: "ң",
|
|
63
|
-
|
|
64
|
-
// Extra letters
|
|
65
|
-
Y: "Й",
|
|
66
|
-
y: "й",
|
|
67
|
-
W: "Ў",
|
|
68
|
-
w: "ў",
|
|
69
|
-
|
|
70
|
-
// Digraphs
|
|
71
|
-
Sh: "Ш",
|
|
72
|
-
sh: "ш",
|
|
73
|
-
SH: "Ш",
|
|
74
|
-
Yu: "Ю",
|
|
75
|
-
yu: "ю",
|
|
76
|
-
Ya: "Я",
|
|
77
|
-
ya: "я",
|
|
78
|
-
Yo: "Ё",
|
|
79
|
-
yo: "ё",
|
|
80
|
-
|
|
81
|
-
Ch: "Ч",
|
|
82
|
-
ch: "ч",
|
|
83
|
-
CH: "Ч",
|
|
84
|
-
|
|
85
|
-
// Optional / borrowed letters
|
|
86
|
-
C: "Ц",
|
|
87
|
-
c: "ц",
|
|
88
|
-
};
|
|
89
|
-
|
|
90
|
-
const cyrillicToLatinMap = {
|
|
91
|
-
А: "A",
|
|
92
|
-
а: "a",
|
|
93
|
-
Ә: "Á",
|
|
94
|
-
ә: "á",
|
|
95
|
-
Б: "B",
|
|
96
|
-
б: "b",
|
|
97
|
-
В: "V",
|
|
98
|
-
в: "v",
|
|
99
|
-
Г: "G",
|
|
100
|
-
г: "g",
|
|
101
|
-
Ғ: "Ǵ",
|
|
102
|
-
ғ: "ǵ",
|
|
103
|
-
Д: "D",
|
|
104
|
-
д: "d",
|
|
105
|
-
Е: "E",
|
|
106
|
-
е: "e",
|
|
107
|
-
Ё: "Yo",
|
|
108
|
-
ё: "yo",
|
|
109
|
-
Ж: "J",
|
|
110
|
-
ж: "j",
|
|
111
|
-
З: "Z",
|
|
112
|
-
з: "z",
|
|
113
|
-
И: "I",
|
|
114
|
-
и: "i",
|
|
115
|
-
Й: "Y",
|
|
116
|
-
й: "y",
|
|
117
|
-
К: "K",
|
|
118
|
-
к: "k",
|
|
119
|
-
Қ: "Q",
|
|
120
|
-
қ: "q",
|
|
121
|
-
Л: "L",
|
|
122
|
-
л: "l",
|
|
123
|
-
М: "M",
|
|
124
|
-
м: "m",
|
|
125
|
-
Н: "N",
|
|
126
|
-
н: "n",
|
|
127
|
-
Ң: "Ń",
|
|
128
|
-
ң: "ń",
|
|
129
|
-
О: "O",
|
|
130
|
-
о: "o",
|
|
131
|
-
Ө: "Ó",
|
|
132
|
-
ө: "ó",
|
|
133
|
-
П: "P",
|
|
134
|
-
п: "p",
|
|
135
|
-
Р: "R",
|
|
136
|
-
р: "r",
|
|
137
|
-
С: "S",
|
|
138
|
-
с: "s",
|
|
139
|
-
Т: "T",
|
|
140
|
-
т: "t",
|
|
141
|
-
У: "U",
|
|
142
|
-
у: "u",
|
|
143
|
-
Ү: "Ú",
|
|
144
|
-
ү: "ú",
|
|
145
|
-
Ў: "W",
|
|
146
|
-
ў: "w",
|
|
147
|
-
Ф: "F",
|
|
148
|
-
ф: "f",
|
|
149
|
-
Х: "X",
|
|
150
|
-
х: "x",
|
|
151
|
-
Ҳ: "H",
|
|
152
|
-
ҳ: "h",
|
|
153
|
-
Ш: "Sh",
|
|
154
|
-
ш: "sh",
|
|
155
|
-
Ч: "Ch",
|
|
156
|
-
ч: "ch",
|
|
157
|
-
Щ: "Sh",
|
|
158
|
-
щ: "sh", // optional
|
|
159
|
-
Ы: "Í",
|
|
160
|
-
ы: "ı",
|
|
161
|
-
|
|
162
|
-
// Borrowed/Russian letters
|
|
163
|
-
Ц: "C",
|
|
164
|
-
ц: "c",
|
|
165
|
-
Э: "E",
|
|
166
|
-
э: "e",
|
|
167
|
-
Ю: "Yu",
|
|
168
|
-
ю: "yu",
|
|
169
|
-
Я: "Ya",
|
|
170
|
-
я: "ya",
|
|
171
|
-
Ъ: "",
|
|
172
|
-
ъ: "",
|
|
173
|
-
Ь: "",
|
|
174
|
-
ь: "",
|
|
175
|
-
};
|
|
176
|
-
|
|
177
|
-
function latinToCyrillic(text) {
|
|
178
|
-
let result = "";
|
|
179
|
-
|
|
180
|
-
for (let i = 0; i < text.length; i++) {
|
|
181
|
-
let twoChars = text[i] + (text[i + 1] || "");
|
|
182
|
-
if (latinToCyrillicMap[twoChars]) {
|
|
183
|
-
result += latinToCyrillicMap[twoChars];
|
|
184
|
-
i++;
|
|
185
|
-
continue;
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
let oneChar = text[i];
|
|
189
|
-
if (latinToCyrillicMap[oneChar]) {
|
|
190
|
-
result += latinToCyrillicMap[oneChar];
|
|
191
|
-
} else {
|
|
192
|
-
result += oneChar;
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
return result;
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
function cyrillicToLatin(text) {
|
|
200
|
-
let result = "";
|
|
201
|
-
|
|
202
|
-
for (let i = 0; i < text.length; i++) {
|
|
203
|
-
const char = text[i];
|
|
204
|
-
|
|
205
|
-
if (cyrillicToLatinMap[char] !== undefined) {
|
|
206
|
-
result += cyrillicToLatinMap[char];
|
|
207
|
-
} else {
|
|
208
|
-
result += char;
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
return result;
|
|
213
|
-
}
|
|
1
|
+
const { latinToCyrillic, cyrillicToLatin } = require("./src/transliterate");
|
|
2
|
+
const { numberToText } = require("./src/numbers");
|
|
214
3
|
|
|
215
4
|
module.exports = {
|
|
216
5
|
latinToCyrillic,
|
|
217
6
|
cyrillicToLatin,
|
|
7
|
+
numberToText,
|
|
218
8
|
};
|
package/package.json
CHANGED
|
@@ -1,18 +1,21 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "kalpak-js",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"main": "index.js",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"test": "echo \"Error: no test specified\" && exit 1"
|
|
7
7
|
},
|
|
8
|
-
"description": "
|
|
8
|
+
"description": "Karakalpak language tools: transliteration (Latin/Cyrillic) and number-to-text conversion.",
|
|
9
9
|
"keywords": [
|
|
10
10
|
"karakalpak",
|
|
11
11
|
"transliteration",
|
|
12
12
|
"cyrillic",
|
|
13
13
|
"latin",
|
|
14
14
|
"qaraqalpaq",
|
|
15
|
-
"language"
|
|
15
|
+
"language",
|
|
16
|
+
"numbers",
|
|
17
|
+
"karakalpakstan",
|
|
18
|
+
"uzbekistan"
|
|
16
19
|
],
|
|
17
20
|
"author": "Ishipiskenler",
|
|
18
21
|
"license": "MIT",
|
package/src/numbers.js
ADDED
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
// 1. Define the building blocks
|
|
2
|
+
const digits = [
|
|
3
|
+
"nól",
|
|
4
|
+
"bir",
|
|
5
|
+
"eki",
|
|
6
|
+
"úsh",
|
|
7
|
+
"tórt",
|
|
8
|
+
"bes",
|
|
9
|
+
"altı",
|
|
10
|
+
"jeti",
|
|
11
|
+
"segiz",
|
|
12
|
+
"toǵız",
|
|
13
|
+
];
|
|
14
|
+
|
|
15
|
+
const tens = {
|
|
16
|
+
10: "on",
|
|
17
|
+
20: "jigirma",
|
|
18
|
+
30: "otız",
|
|
19
|
+
40: "qırıq",
|
|
20
|
+
50: "eliw",
|
|
21
|
+
60: "alpıs",
|
|
22
|
+
70: "jetpis",
|
|
23
|
+
80: "seksen",
|
|
24
|
+
90: "toqsan",
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
const hundreds = {
|
|
28
|
+
100: "bir júz",
|
|
29
|
+
200: "eki júz",
|
|
30
|
+
300: "úsh júz",
|
|
31
|
+
400: "tórt júz",
|
|
32
|
+
500: "bes júz",
|
|
33
|
+
600: "altı júz",
|
|
34
|
+
700: "jeti júz",
|
|
35
|
+
800: "segiz júz",
|
|
36
|
+
900: "toǵız júz",
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
function numberToText(num) {
|
|
40
|
+
// 0. Safety check (Validation)
|
|
41
|
+
if (typeof num !== "number") return "Error: Not a number";
|
|
42
|
+
if (num < 0 || num > 1000000000000)
|
|
43
|
+
return "Error: Only 0-1000000000000 (up to one trillion) supported for now";
|
|
44
|
+
|
|
45
|
+
// 1. Handle exact whole numbers
|
|
46
|
+
if (num === 100) return "júz";
|
|
47
|
+
if (num === 1000) return "miń";
|
|
48
|
+
if (num === 10000) return "on miń";
|
|
49
|
+
if (num === 100000) return "júz miń";
|
|
50
|
+
if (num === 1000000) return "bir million";
|
|
51
|
+
if (num === 10000000) return "on million";
|
|
52
|
+
if (num === 100000000) return "júz million";
|
|
53
|
+
if (num === 1000000000) return "bir milliard";
|
|
54
|
+
if (num === 10000000000) return "on milliard";
|
|
55
|
+
if (num === 100000000000) return "júz milliard";
|
|
56
|
+
if (num === 1000000000000) return "bir trillion";
|
|
57
|
+
|
|
58
|
+
// 2. Handle 0-9
|
|
59
|
+
if (num < 10) {
|
|
60
|
+
return digits[num];
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// 3. Handle 10-99
|
|
64
|
+
if (num > 9 && num < 100) {
|
|
65
|
+
const tenPart = Math.floor(num / 10) * 10; // e.g. 42 -> 40
|
|
66
|
+
const onePart = num % 10; // e.g. 42 -> 2
|
|
67
|
+
|
|
68
|
+
const tenText = tens[tenPart];
|
|
69
|
+
|
|
70
|
+
// If perfectly 20, 30, 40... (onePart is 0), just return the tenText
|
|
71
|
+
if (onePart === 0) {
|
|
72
|
+
return tenText;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Otherwise combine them: "qırıq" + " " + "eki"
|
|
76
|
+
const oneText = digits[onePart];
|
|
77
|
+
return `${tenText} ${oneText}`;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Handle 100-999
|
|
81
|
+
if (num >= 100 && num < 1000) {
|
|
82
|
+
const hundredsPart = Math.floor(num / 100) * 100;
|
|
83
|
+
const tenPart = Math.floor((num % 100) / 10) * 10;
|
|
84
|
+
const onePart = (num % 100) % 10;
|
|
85
|
+
|
|
86
|
+
const hundredsText = hundreds[hundredsPart];
|
|
87
|
+
const tenText = tens[tenPart];
|
|
88
|
+
const oneText = digits[onePart];
|
|
89
|
+
|
|
90
|
+
if (tenPart === 0 && onePart === 0) {
|
|
91
|
+
return `${hundreds[num]}`;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// If the ten-part is zero, return hundreds and one-part only (101,102, ...)
|
|
95
|
+
if (tenPart === 0) {
|
|
96
|
+
return `${hundredsText} ${oneText}`;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// If the one-part is zero, return hundreds-part and tens-part only (110,120, ...)
|
|
100
|
+
if (onePart === 0) {
|
|
101
|
+
return `${hundredsText} ${tenText}`;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// You know this broo :)
|
|
105
|
+
return `${hundredsText} ${tenText} ${oneText}`;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// Handle (1000 - 999999) (thousands)
|
|
109
|
+
if (num >= 1000 && num < 1000000) {
|
|
110
|
+
const thousandsPart = Math.floor(num / 1000);
|
|
111
|
+
const remainder = num % 1000;
|
|
112
|
+
|
|
113
|
+
if (remainder === 0) {
|
|
114
|
+
return `${numberToText(thousandsPart)} miń`;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
return `${numberToText(thousandsPart)} miń ${numberToText(remainder)}`;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// Handle (million - billion) (millions)
|
|
121
|
+
if (num >= 1000000 && num < 1000000000) {
|
|
122
|
+
const millionsPart = Math.floor(num / 1000000);
|
|
123
|
+
const remainder = num % 1000000;
|
|
124
|
+
|
|
125
|
+
if (remainder === 0) {
|
|
126
|
+
return `${numberToText(millionsPart)} million`;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
return `${numberToText(millionsPart)} million ${numberToText(remainder)}`;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// Handle (billion - trillion) (billions)
|
|
133
|
+
if (num >= 1000000000 && num < 1000000000000) {
|
|
134
|
+
const billionsPart = Math.floor(num / 1000000000);
|
|
135
|
+
const remainder = num % 1000000000;
|
|
136
|
+
|
|
137
|
+
if (remainder === 0) {
|
|
138
|
+
return `${numberToText(billionsPart)} milliard`;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
return `${numberToText(billionsPart)} milliard ${numberToText(remainder)}`;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
module.exports = { numberToText };
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
const latinToCyrillicMap = {
|
|
2
|
+
// Basic letters
|
|
3
|
+
A: "А",
|
|
4
|
+
a: "а",
|
|
5
|
+
B: "Б",
|
|
6
|
+
b: "б",
|
|
7
|
+
D: "Д",
|
|
8
|
+
d: "д",
|
|
9
|
+
E: "Е",
|
|
10
|
+
e: "е",
|
|
11
|
+
F: "Ф",
|
|
12
|
+
f: "ф",
|
|
13
|
+
G: "Г",
|
|
14
|
+
g: "г",
|
|
15
|
+
H: "Ҳ",
|
|
16
|
+
h: "ҳ",
|
|
17
|
+
X: "Х",
|
|
18
|
+
x: "х",
|
|
19
|
+
J: "Ж",
|
|
20
|
+
j: "ж",
|
|
21
|
+
K: "К",
|
|
22
|
+
k: "к",
|
|
23
|
+
Q: "Қ",
|
|
24
|
+
q: "қ",
|
|
25
|
+
L: "Л",
|
|
26
|
+
l: "л",
|
|
27
|
+
M: "М",
|
|
28
|
+
m: "м",
|
|
29
|
+
N: "Н",
|
|
30
|
+
n: "н",
|
|
31
|
+
O: "О",
|
|
32
|
+
o: "о",
|
|
33
|
+
P: "П",
|
|
34
|
+
p: "п",
|
|
35
|
+
R: "Р",
|
|
36
|
+
r: "р",
|
|
37
|
+
S: "С",
|
|
38
|
+
s: "с",
|
|
39
|
+
T: "Т",
|
|
40
|
+
t: "т",
|
|
41
|
+
U: "У",
|
|
42
|
+
u: "у",
|
|
43
|
+
V: "В",
|
|
44
|
+
v: "в",
|
|
45
|
+
Z: "З",
|
|
46
|
+
z: "з",
|
|
47
|
+
|
|
48
|
+
// Special letters
|
|
49
|
+
Á: "Ә",
|
|
50
|
+
á: "ә",
|
|
51
|
+
Ó: "Ө",
|
|
52
|
+
ó: "ө",
|
|
53
|
+
Ú: "Ү",
|
|
54
|
+
ú: "ү",
|
|
55
|
+
I: "И",
|
|
56
|
+
i: "и",
|
|
57
|
+
Í: "Ы",
|
|
58
|
+
ı: "ы",
|
|
59
|
+
Ǵ: "Ғ",
|
|
60
|
+
ǵ: "ғ",
|
|
61
|
+
Ń: "Ң",
|
|
62
|
+
ń: "ң",
|
|
63
|
+
|
|
64
|
+
// Extra letters
|
|
65
|
+
Y: "Й",
|
|
66
|
+
y: "й",
|
|
67
|
+
W: "Ў",
|
|
68
|
+
w: "ў",
|
|
69
|
+
|
|
70
|
+
// Digraphs
|
|
71
|
+
Sh: "Ш",
|
|
72
|
+
sh: "ш",
|
|
73
|
+
SH: "Ш",
|
|
74
|
+
Yu: "Ю",
|
|
75
|
+
yu: "ю",
|
|
76
|
+
Ya: "Я",
|
|
77
|
+
ya: "я",
|
|
78
|
+
Yo: "Ё",
|
|
79
|
+
yo: "ё",
|
|
80
|
+
|
|
81
|
+
Ch: "Ч",
|
|
82
|
+
ch: "ч",
|
|
83
|
+
CH: "Ч",
|
|
84
|
+
|
|
85
|
+
// Optional / borrowed letters
|
|
86
|
+
C: "Ц",
|
|
87
|
+
c: "ц",
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
const cyrillicToLatinMap = {
|
|
91
|
+
А: "A",
|
|
92
|
+
а: "a",
|
|
93
|
+
Ә: "Á",
|
|
94
|
+
ә: "á",
|
|
95
|
+
Б: "B",
|
|
96
|
+
б: "b",
|
|
97
|
+
В: "V",
|
|
98
|
+
в: "v",
|
|
99
|
+
Г: "G",
|
|
100
|
+
г: "g",
|
|
101
|
+
Ғ: "Ǵ",
|
|
102
|
+
ғ: "ǵ",
|
|
103
|
+
Д: "D",
|
|
104
|
+
д: "d",
|
|
105
|
+
Е: "E",
|
|
106
|
+
е: "e",
|
|
107
|
+
Ё: "Yo",
|
|
108
|
+
ё: "yo",
|
|
109
|
+
Ж: "J",
|
|
110
|
+
ж: "j",
|
|
111
|
+
З: "Z",
|
|
112
|
+
з: "z",
|
|
113
|
+
И: "I",
|
|
114
|
+
и: "i",
|
|
115
|
+
Й: "Y",
|
|
116
|
+
й: "y",
|
|
117
|
+
К: "K",
|
|
118
|
+
к: "k",
|
|
119
|
+
Қ: "Q",
|
|
120
|
+
қ: "q",
|
|
121
|
+
Л: "L",
|
|
122
|
+
л: "l",
|
|
123
|
+
М: "M",
|
|
124
|
+
м: "m",
|
|
125
|
+
Н: "N",
|
|
126
|
+
н: "n",
|
|
127
|
+
Ң: "Ń",
|
|
128
|
+
ң: "ń",
|
|
129
|
+
О: "O",
|
|
130
|
+
о: "o",
|
|
131
|
+
Ө: "Ó",
|
|
132
|
+
ө: "ó",
|
|
133
|
+
П: "P",
|
|
134
|
+
п: "p",
|
|
135
|
+
Р: "R",
|
|
136
|
+
р: "r",
|
|
137
|
+
С: "S",
|
|
138
|
+
с: "s",
|
|
139
|
+
Т: "T",
|
|
140
|
+
т: "t",
|
|
141
|
+
У: "U",
|
|
142
|
+
у: "u",
|
|
143
|
+
Ү: "Ú",
|
|
144
|
+
ү: "ú",
|
|
145
|
+
Ў: "W",
|
|
146
|
+
ў: "w",
|
|
147
|
+
Ф: "F",
|
|
148
|
+
ф: "f",
|
|
149
|
+
Х: "X",
|
|
150
|
+
х: "x",
|
|
151
|
+
Ҳ: "H",
|
|
152
|
+
ҳ: "h",
|
|
153
|
+
Ш: "Sh",
|
|
154
|
+
ш: "sh",
|
|
155
|
+
Ч: "Ch",
|
|
156
|
+
ч: "ch",
|
|
157
|
+
Щ: "Sh",
|
|
158
|
+
щ: "sh", // optional
|
|
159
|
+
Ы: "Í",
|
|
160
|
+
ы: "ı",
|
|
161
|
+
|
|
162
|
+
// Borrowed/Russian letters
|
|
163
|
+
Ц: "C",
|
|
164
|
+
ц: "c",
|
|
165
|
+
Э: "E",
|
|
166
|
+
э: "e",
|
|
167
|
+
Ю: "Yu",
|
|
168
|
+
ю: "yu",
|
|
169
|
+
Я: "Ya",
|
|
170
|
+
я: "ya",
|
|
171
|
+
Ъ: "",
|
|
172
|
+
ъ: "",
|
|
173
|
+
Ь: "",
|
|
174
|
+
ь: "",
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
function latinToCyrillic(text) {
|
|
178
|
+
let result = "";
|
|
179
|
+
|
|
180
|
+
for (let i = 0; i < text.length; i++) {
|
|
181
|
+
let twoChars = text[i] + (text[i + 1] || "");
|
|
182
|
+
if (latinToCyrillicMap[twoChars]) {
|
|
183
|
+
result += latinToCyrillicMap[twoChars];
|
|
184
|
+
i++;
|
|
185
|
+
continue;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
let oneChar = text[i];
|
|
189
|
+
if (latinToCyrillicMap[oneChar]) {
|
|
190
|
+
result += latinToCyrillicMap[oneChar];
|
|
191
|
+
} else {
|
|
192
|
+
result += oneChar;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
return result;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
function cyrillicToLatin(text) {
|
|
200
|
+
let result = "";
|
|
201
|
+
|
|
202
|
+
for (let i = 0; i < text.length; i++) {
|
|
203
|
+
const char = text[i];
|
|
204
|
+
|
|
205
|
+
if (cyrillicToLatinMap[char] !== undefined) {
|
|
206
|
+
result += cyrillicToLatinMap[char];
|
|
207
|
+
} else {
|
|
208
|
+
result += char;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
return result;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
module.exports = { latinToCyrillic, cyrillicToLatin };
|