marathi-transliterate 1.2.0 → 1.3.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 CHANGED
@@ -14,6 +14,8 @@ Most existing Sanskrit/IAST transliteration libraries convert `sakhar` to **स
14
14
 
15
15
  In everyday reality, people in Maharashtra type phonetically:
16
16
  - `sakhar` → **साखर**
17
+ - `jaad` → **जाड**
18
+ - `daba` → **डबा**
17
19
  - `kanda` → **कांदा**
18
20
  - `batata` → **बटाटा**
19
21
  - `mith` → **मीठ**
@@ -53,6 +55,9 @@ import { transliterate, transliterateWord } from 'marathi-transliterate';
53
55
 
54
56
  // Single word transliteration
55
57
  transliterateWord('sakhar'); // → 'साखर'
58
+ transliterateWord('jaad'); // → 'जाड'
59
+ transliterateWord('Daba'); // → 'डबा'
60
+ transliterateWord('D'); // → 'ड' (vs 'd' → 'द')
56
61
  transliterateWord('kanda'); // → 'कांदा'
57
62
  transliterateWord('batata'); // → 'बटाटा'
58
63
  transliterateWord('namaskar'); // → 'नमस्कार'
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "marathi-transliterate",
3
- "version": "1.2.0",
3
+ "version": "1.3.0",
4
4
  "description": "Zero-dependency, offline-first Marathi / Devanagari phonetic transliteration library. Converts English typing to Marathi (e.g. sakhar -> साखर) seamlessly in plain JS, Node.js, and frontend frameworks.",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
package/src/dictionary.js CHANGED
@@ -552,6 +552,212 @@ export const MARATHI_DICTIONARY = {
552
552
  'sejal': 'सेजल',
553
553
  'nilesh': 'निलेश',
554
554
  'shailesh': 'शैलेश',
555
- 'kamlesh': 'कमलेश'
555
+ 'kamlesh': 'कमलेश',
556
+
557
+ // --- Grocery & Household with ड / ढ / ट / ठ / द / ध ---
558
+ "jaad": "जाड",
559
+ "jad": "जाड",
560
+ "jada": "जाडा",
561
+ "jaada": "जाडा",
562
+ "jadi": "जाडी",
563
+ "jaadi": "जाडी",
564
+ "barik": "बारीक",
565
+ "bareek": "बारीक",
566
+ "baareek": "बारीक",
567
+ "jadpoha": "जाड पोहे",
568
+ "jaadpoha": "जाड पोहे",
569
+ "jaadpohe": "जाड पोहे",
570
+ "jadrava": "जाड रवा",
571
+ "jaadrava": "जाड रवा",
572
+ "barikpoha": "बारीक पोहे",
573
+ "barikpohe": "बारीक पोहे",
574
+ "barikrava": "बारीक रवा",
575
+ "daba": "डबा",
576
+ "dabba": "डबा",
577
+ "dabi": "डबी",
578
+ "dabbi": "डबी",
579
+ "papad": "पापड",
580
+ "paapad": "पापड",
581
+ "kadak": "कडक",
582
+ "laddu": "लाडू",
583
+ "ladoo": "लाडू",
584
+ "laadu": "लाडू",
585
+ "peda": "पेढा",
586
+ "pedha": "पेढा",
587
+ "pendha": "पेंढा",
588
+ "bhendi": "भेंडी",
589
+ "bhindi": "भेंडी",
590
+ "bhende": "भेंडे",
591
+ "thik": "ठीक",
592
+ "theek": "ठीक",
593
+ "dhag": "ढग",
594
+ "dhol": "ढोल",
595
+ "dholak": "ढोलक",
596
+ "dholki": "ढोलकी",
597
+ "khadda": "खड्डा",
598
+ "khada": "खड्डा",
599
+ "tambda": "तांबडा",
600
+ "tambadi": "तांबडी",
601
+ "pandhra": "पांढरा",
602
+ "pandhari": "पांढरी",
603
+ "korda": "कोरडा",
604
+ "kordi": "कोरडी",
605
+ "thanda": "थंड",
606
+ "thand": "थंड",
607
+ "god": "गोड",
608
+ "godd": "गोड",
609
+ "dodka": "दोडका",
610
+ "dodke": "दोडके",
611
+ "karela": "कारले",
612
+ "karle": "कारले",
613
+ "bhopla": "भोपळा",
614
+ "ghevda": "घेवडा",
615
+ "ghevada": "घेवडा",
616
+ "danda": "दांडा",
617
+ "dandi": "दांडी",
618
+ "dada": "दादा",
619
+ "dadi": "दादी",
620
+ "undi": "उंडी",
621
+ "and": "अंडे",
622
+ "ande": "अंडे",
623
+ "anda": "अंडे",
624
+ "eggs": "अंडी",
625
+ "egg": "अंडे",
626
+ "powder": "पावडर",
627
+ "pavdar": "पावडर",
628
+ "detergent": "डिटर्जंट",
629
+ "doctor": "डॉक्टर",
630
+ "order": "ऑर्डर",
631
+ "board": "बोर्ड",
632
+ "card": "कार्ड",
633
+ "credit": "क्रेडिट",
634
+ "debit": "डेबिट",
635
+ "disco": "डिस्को",
636
+ "diesel": "डिझेल",
637
+ "petrol": "पेट्रोल",
638
+ "speed": "स्पीड",
639
+ "driver": "ड्रायव्हर",
640
+ "drive": "ड्राइव्ह",
641
+
642
+ // --- Enhanced Marathi Daily Essentials & Corner Cases ---
643
+ "ratri": "रात्री",
644
+ "raatri": "रात्री",
645
+ "vikri": "विक्री",
646
+ "kharedi": "खरेदी",
647
+ "supari": "सुपारी",
648
+ "chutney": "चटणी",
649
+ "chatani": "चटणी",
650
+ "limbu": "लिंबू",
651
+ "nimbu": "लिंबू",
652
+ "bhakri": "भाकरी",
653
+ "poli": "पोळी",
654
+ "chikki": "चिक्की",
655
+ "farsan": "फरसाण",
656
+ "chivda": "चिवडा",
657
+ "bhadang": "भडंग",
658
+ "shev": "शेव",
659
+ "bakarwadi": "बाकरवडी",
660
+ "shrikhand": "श्रीखंड",
661
+ "amrakhand": "आम्रखंड",
662
+ "basundi": "बासुंदी",
663
+ "kurdaya": "कुरडया",
664
+ "papadya": "पापड्या",
665
+ "khari": "खारी",
666
+ "toast": "टोस्ट",
667
+ "pav": "पाव",
668
+ "bread": "ब्रेड",
669
+ "butter": "बटर",
670
+ "loni": "लोणी",
671
+ "sauce": "सॉस",
672
+ "jam": "जॅम",
673
+ "noodle": "नुडल्स",
674
+ "noodles": "नुडल्स",
675
+ "pasta": "पास्ता",
676
+ "macaroni": "मॅकरोनी",
677
+ "cornflakes": "कॉर्नफ्लेक्स",
678
+ "oats": "ओट्स",
679
+ "sendha": "सेंधा",
680
+ "sendhav": "सेंधव",
681
+ "rocksalt": "सेंधव मीठ",
682
+ "sabudana": "साबुदाणा",
683
+ "bhagar": "भगर",
684
+ "rajgira": "राजगिरा",
685
+ "singhada": "शिंगाडा",
686
+ "makhana": "मखाना",
687
+ "dryfruit": "ड्रायफ्रूट",
688
+ "dryfruits": "ड्रायफ्रूट्स",
689
+ "custard": "कस्टर्ड",
690
+ "bakingpowder": "बेकिंग पावडर",
691
+ "bakingsoda": "बेकिंग सोडा",
692
+ "soda": "सोडा",
693
+ "eno": "इनो",
694
+ "matchbox": "काडीपेटी",
695
+ "diya": "दिवा",
696
+ "vaat": "वात",
697
+ "kapus": "कापूस",
698
+ "gangajal": "गंगाजल",
699
+ "gulabjal": "गुलाबजल",
700
+ "kumkum": "कुंकू",
701
+ "haladikunku": "हळदीकुंकू",
702
+ "rangoli": "रांगोळी",
703
+ "shampoo": "शॅम्पू",
704
+ "conditioner": "कंडिशनर",
705
+ "harpic": "हार्पिक",
706
+ "lizol": "लायझोल",
707
+ "phenyl": "फिनाईल",
708
+ "closeup": "क्लोजअप",
709
+ "pepsodent": "पेप्सोडेंट",
710
+ "sensodyne": "सेन्सॉडीन",
711
+ "brush": "ब्रश",
712
+ "dettol": "डेटॉल",
713
+ "savlon": "सॅव्हलॉन",
714
+ "rin": "रिन",
715
+ "tide": "टाईड",
716
+ "aerial": "एरियल",
717
+ "wheel": "व्हील",
718
+ "ghadi": "घडी",
719
+ "nirma": "निरमा",
720
+ "vim": "विम",
721
+ "exo": "एक्सो",
722
+ "prill": "प्रिल",
723
+ "scrubber": "स्क्रबर",
724
+ "sponge": "स्पंज",
725
+ "jhadu": "झाडू",
726
+ "pocha": "पोछा",
727
+ "bucket": "बादली",
728
+ "badli": "बादली",
729
+ "mug": "मग",
730
+ "duster": "डस्टर",
731
+ "tissue": "टिश्यू",
732
+ "foil": "फॉइल",
733
+ "plastic": "प्लास्टिक",
734
+ "pishvi": "पिशवी",
735
+ "kilo": "किलो",
736
+ "gram": "ग्रॅम",
737
+ "liter": "लिटर",
738
+ "militre": "मिली",
739
+ "darzon": "डझन",
740
+ "dozen": "डझन",
741
+ "dazan": "डझन",
742
+ "nag": "नग",
743
+ "box": "बॉक्स",
744
+ "carton": "खोके",
745
+ "goni": "गोणी",
746
+ "pote": "पोते",
747
+ "truck": "ट्रक",
748
+ "tractor": "ट्रॅक्टर",
749
+ "tempo": "टॅम्पो",
750
+
751
+ "pani": "पाणी",
752
+ "paani": "पाणी",
753
+ "water": "पाणी",
754
+ "paan": "पान",
755
+ "chaan": "छान",
756
+ "chan": "छान",
757
+ "man": "मन",
758
+ "aan": "आण",
759
+ "bana": "बाण",
760
+ "dane": "दाणे",
761
+ "dana": "दाणा",
556
762
  };
557
763
 
package/src/index.js CHANGED
@@ -128,18 +128,85 @@ export function getSuggestions(word, options = {}) {
128
128
  const phonetic = phoneticTransliterateWord(word);
129
129
  if (phonetic) add(phonetic);
130
130
 
131
- // 4. Smart Marathi ळ (LLA) and ल (LA) variants expansion
131
+ // 4. Smart Marathi phonetic variants expansion (ळ/ल, ड/द, ढ/ध, ट/त, ठ/थ, ण/न, ष/श, झ/ज, ई/इ, ऊ/उ)
132
132
  const initialCandidates = [...suggestions];
133
133
  for (const s of initialCandidates) {
134
+ // 4a. ळ (LLA) and ल (LA) - e.g. "keli" -> "केळी", "bhusal" -> "भुसाळ"
134
135
  if (s.includes("ल")) {
135
- // Special Marathi phonetic rule: words ending in "al" often end in "ाळ" (e.g. bhusal -> भुसाळ)
136
- if (clean.endsWith("al") && s.endsWith("ल")) {
136
+ if (clean.endsWith("al") && s.endsWith("ल") && !s.endsWith("ाल")) {
137
137
  add(s.slice(0, -1) + "ाळ");
138
138
  }
139
139
  add(s.replace(/ल/g, "ळ"));
140
140
  } else if (s.includes("ळ")) {
141
141
  add(s.replace(/ळ/g, "ल"));
142
142
  }
143
+
144
+ // 4b. ड (DDA) and द (DA) - e.g. "Jaad" -> "जाड", "Daba" -> "डबा", "kadak" -> "कडक"
145
+ if (s.includes("द")) {
146
+ if (clean.endsWith("ad") && s.endsWith("द") && !s.endsWith("ाद")) {
147
+ add(s.slice(0, -1) + "ाड");
148
+ }
149
+ add(s.replace(/द/g, "ड"));
150
+ } else if (s.includes("ड")) {
151
+ add(s.replace(/ड/g, "द"));
152
+ }
153
+
154
+ // 4c. ढ (DDHA) and ध (DHA) - e.g. "dhag" -> "ढग", "dhol" -> "ढोल"
155
+ if (s.includes("ध")) {
156
+ add(s.replace(/ध/g, "ढ"));
157
+ } else if (s.includes("ढ")) {
158
+ add(s.replace(/ढ/g, "ध"));
159
+ }
160
+
161
+ // 4d. ट (TTA) and त (TA) - e.g. "batata" -> "बटाटा", "tomato" -> "टोमॅटो"
162
+ if (s.includes("त")) {
163
+ add(s.replace(/त/g, "ट"));
164
+ } else if (s.includes("ट")) {
165
+ add(s.replace(/त/g, "त"));
166
+ }
167
+
168
+ // 4e. ठ (TTHA) and थ (THA) - e.g. "thik" -> "ठीक", "path" -> "पाठ"
169
+ if (s.includes("थ")) {
170
+ add(s.replace(/थ/g, "ठ"));
171
+ } else if (s.includes("ठ")) {
172
+ add(s.replace(/ठ/g, "थ"));
173
+ }
174
+
175
+ // 4f. ण (NNA) and न (NA) - e.g. "pani" -> "पाणी", "bana" -> "बाण", "dane" -> "दाणे"
176
+ if (s.includes("न")) {
177
+ add(s.replace(/न/g, "ण"));
178
+ } else if (s.includes("ण")) {
179
+ add(s.replace(/ण/g, "न"));
180
+ }
181
+
182
+ // 4g. ष (SSA) and श (SHA) - e.g. "vishesh" -> "विशेष"
183
+ if (s.includes("श")) {
184
+ add(s.replace(/श/g, "ष"));
185
+ } else if (s.includes("ष")) {
186
+ add(s.replace(/ष/g, "श"));
187
+ }
188
+
189
+ // 4h. झ (JHA) and ज (JA) - e.g. "jhadu" -> "झाडू"
190
+ if (s.includes("ज") && (clean.includes("jh") || clean.includes("zh") || clean.includes("z"))) {
191
+ add(s.replace(/ज/g, "झ"));
192
+ }
193
+
194
+ // 4i. Authentic Marathi final dirgha vowel rules (मराठी शुद्धलेखन: अंत्य इकार/उकार दीर्घ)
195
+ if (s.endsWith("ि")) {
196
+ add(s.slice(0, -1) + "ी");
197
+ } else if (s.endsWith("ी")) {
198
+ add(s.slice(0, -1) + "ि");
199
+ }
200
+ if (s.endsWith("ु")) {
201
+ add(s.slice(0, -1) + "ू");
202
+ } else if (s.endsWith("ू")) {
203
+ add(s.slice(0, -1) + "ु");
204
+ }
205
+
206
+ // 4j. Word-ending "a" kana variants (e.g. rama -> रामा & राम)
207
+ if (clean.endsWith("a") && s.endsWith("ा")) {
208
+ add(s.slice(0, -1));
209
+ }
143
210
  }
144
211
 
145
212
  // 5. Prefix matches from dictionary (if clean.length >= 3)
package/src/phonetics.js CHANGED
@@ -5,108 +5,118 @@
5
5
 
6
6
  const CONSONANTS = [
7
7
  // Multi-character special combinations
8
- { en: 'dny', mr: 'ज्ञ' },
9
- { en: 'jn', mr: 'ज्ञ' },
10
- { en: 'gy', mr: 'ज्ञ' },
11
- { en: 'ksh', mr: 'क्ष' },
12
- { en: 'shr', mr: 'श्र' },
13
- { en: 'chh', mr: 'छ' },
14
- { en: 'ch', mr: 'च' },
15
- { en: 'kh', mr: 'ख' },
16
- { en: 'gh', mr: 'घ' },
17
- { en: 'jh', mr: 'झ' },
18
- { en: 'zh', mr: 'झ' },
19
- { en: 'th', mr: 'थ' },
20
- { en: 'dh', mr: 'ध' },
21
- { en: 'ph', mr: 'फ' },
22
- { en: 'bh', mr: 'भ' },
23
- { en: 'shh', mr: 'ष' },
24
- { en: 'sh', mr: 'श' },
25
- { en: 'ng', mr: 'ङ' },
26
-
27
- // Single consonants
28
- { en: 'k', mr: 'क' },
29
- { en: 'g', mr: 'ग' },
30
- { en: 'j', mr: 'ज' },
31
- { en: 't', mr: 'त' },
32
- { en: 'd', mr: 'द' },
33
- { en: 'n', mr: 'न' },
34
- { en: 'p', mr: 'प' },
35
- { en: 'f', mr: 'फ' },
36
- { en: 'b', mr: 'ब' },
37
- { en: 'm', mr: 'म' },
38
- { en: 'y', mr: 'य' },
39
- { en: 'r', mr: 'र' },
40
- { en: 'l', mr: 'ल' },
41
- { en: 'L', mr: 'ळ' },
42
- { en: 'v', mr: 'व' },
43
- { en: 'w', mr: 'व' },
44
- { en: 's', mr: 'स' },
45
- { en: 'h', mr: 'ह' },
46
- { en: 'x', mr: 'क्ष' },
47
- { en: 'z', mr: 'झ' },
48
- { en: 'T', mr: 'ट' },
49
- { en: 'D', mr: 'ड' },
50
- { en: 'N', mr: 'ण' }
8
+ { en: "dny", mr: "ज्ञ" },
9
+ { en: "jn", mr: "ज्ञ" },
10
+ { en: "gy", mr: "ज्ञ" },
11
+ { en: "ksh", mr: "क्ष" },
12
+ { en: "shr", mr: "श्र" },
13
+ { en: "chh", mr: "छ" },
14
+ { en: "ch", mr: "च" },
15
+ { en: "kh", mr: "ख" },
16
+ { en: "gh", mr: "घ" },
17
+ { en: "jh", mr: "झ" },
18
+ { en: "zh", mr: "झ" },
19
+ { en: "Dh", mr: "ढ", caseSensitive: true },
20
+ { en: "DH", mr: "ढ", caseSensitive: true },
21
+ { en: "dh", mr: "ध" },
22
+ { en: "Th", mr: "ठ", caseSensitive: true },
23
+ { en: "TH", mr: "ठ", caseSensitive: true },
24
+ { en: "th", mr: "थ" },
25
+ { en: "ph", mr: "फ" },
26
+ { en: "bh", mr: "भ" },
27
+ { en: "shh", mr: "ष" },
28
+ { en: "Sh", mr: "ष", caseSensitive: true },
29
+ { en: "SH", mr: "ष", caseSensitive: true },
30
+ { en: "sh", mr: "श" },
31
+ { en: "ck", mr: "क" },
32
+ { en: "ng", mr: "ङ" },
33
+ { en: "c", mr: "क" },
34
+
35
+ // Single consonants - case-sensitive retroflex & special Marathi sounds FIRST
36
+ { en: "T", mr: "ट", caseSensitive: true },
37
+ { en: "D", mr: "ड", caseSensitive: true },
38
+ { en: "N", mr: "ण", caseSensitive: true },
39
+ { en: "L", mr: "ळ", caseSensitive: true },
40
+
41
+ // Single consonants - standard
42
+ { en: "k", mr: "क" },
43
+ { en: "g", mr: "ग" },
44
+ { en: "j", mr: "ज" },
45
+ { en: "t", mr: "त" },
46
+ { en: "d", mr: "द" },
47
+ { en: "n", mr: "न" },
48
+ { en: "p", mr: "प" },
49
+ { en: "f", mr: "फ" },
50
+ { en: "b", mr: "ब" },
51
+ { en: "m", mr: "म" },
52
+ { en: "y", mr: "य" },
53
+ { en: "r", mr: "र" },
54
+ { en: "l", mr: "ल" },
55
+ { en: "v", mr: "व" },
56
+ { en: "w", mr: "व" },
57
+ { en: "s", mr: "स" },
58
+ { en: "h", mr: "ह" },
59
+ { en: "x", mr: "क्ष" },
60
+ { en: "z", mr: "झ" }
51
61
  ];
52
62
 
53
63
  const INDEPENDENT_VOWELS = [
54
- { en: 'aa', mr: 'आ' },
55
- { en: 'A', mr: 'आ' },
56
- { en: 'a', mr: 'अ' },
57
- { en: 'ee', mr: 'ई' },
58
- { en: 'ii', mr: 'ई' },
59
- { en: 'i', mr: 'इ' },
60
- { en: 'oo', mr: 'ऊ' },
61
- { en: 'uu', mr: 'ऊ' },
62
- { en: 'u', mr: 'उ' },
63
- { en: 'ai', mr: 'ऐ' },
64
- { en: 'ay', mr: 'ऐ' },
65
- { en: 'au', mr: 'औ' },
66
- { en: 'ou', mr: 'औ' },
67
- { en: 'ow', mr: 'औ' },
68
- { en: 'e', mr: 'ए' },
69
- { en: 'o', mr: 'ओ' },
70
- { en: 'am', mr: 'अं' },
71
- { en: 'an', mr: 'अं' },
72
- { en: 'ri', mr: 'ऋ' },
73
- { en: 'ru', mr: 'ऋ' }
64
+ { en: "aa", mr: "आ" },
65
+ { en: "A", mr: "आ" },
66
+ { en: "a", mr: "अ" },
67
+ { en: "ee", mr: "ई" },
68
+ { en: "ii", mr: "ई" },
69
+ { en: "i", mr: "इ" },
70
+ { en: "oo", mr: "ऊ" },
71
+ { en: "uu", mr: "ऊ" },
72
+ { en: "u", mr: "उ" },
73
+ { en: "ai", mr: "ऐ" },
74
+ { en: "ay", mr: "ऐ" },
75
+ { en: "au", mr: "औ" },
76
+ { en: "ou", mr: "औ" },
77
+ { en: "ow", mr: "औ" },
78
+ { en: "e", mr: "ए" },
79
+ { en: "o", mr: "ओ" },
80
+ { en: "am", mr: "अं" },
81
+ { en: "an", mr: "अं" },
82
+ { en: "ri", mr: "ऋ" },
83
+ { en: "ru", mr: "ऋ" },
84
+ { en: "R", mr: "ऋ", caseSensitive: true }
74
85
  ];
75
86
 
76
87
  const MATRAS = [
77
- { en: 'aa', mr: 'ा' },
78
- { en: 'A', mr: 'ा' },
79
- { en: 'a', mr: '' }, // Inherent vowel: cancels halant, no visible matra
80
- { en: 'ee', mr: 'ी' },
81
- { en: 'ii', mr: 'ी' },
82
- { en: 'i', mr: 'ि' },
83
- { en: 'oo', mr: 'ू' },
84
- { en: 'uu', mr: 'ू' },
85
- { en: 'u', mr: 'ु' },
86
- { en: 'ai', mr: 'ै' },
87
- { en: 'ay', mr: 'ै' },
88
- { en: 'au', mr: 'ौ' },
89
- { en: 'ou', mr: 'ौ' },
90
- { en: 'ow', mr: 'ौ' },
91
- { en: 'e', mr: 'े' },
92
- { en: 'o', mr: 'ो' },
93
- { en: 'am', mr: 'ं' },
94
- { en: 'an', mr: 'ं' },
95
- { en: 'ri', mr: 'ृ' },
96
- { en: 'ru', mr: 'ृ' }
88
+ { en: "aa", mr: "ा" },
89
+ { en: "A", mr: "ा" },
90
+ { en: "a", mr: "" }, // Inherent vowel: cancels halant; at word end becomes kana
91
+ { en: "ee", mr: "ी" },
92
+ { en: "ii", mr: "ी" },
93
+ { en: "i", mr: "ि" },
94
+ { en: "oo", mr: "ू" },
95
+ { en: "uu", mr: "ू" },
96
+ { en: "u", mr: "ु" },
97
+ { en: "ai", mr: "ै" },
98
+ { en: "ay", mr: "ै" },
99
+ { en: "au", mr: "ौ" },
100
+ { en: "ou", mr: "ौ" },
101
+ { en: "ow", mr: "ौ" },
102
+ { en: "e", mr: "े" },
103
+ { en: "o", mr: "ो" },
104
+ { en: "am", mr: "ं" },
105
+ { en: "an", mr: "ं" },
106
+ { en: "R", mr: "ृ", caseSensitive: true }
97
107
  ];
98
108
 
99
109
  /**
100
110
  * Phonetically transliterates a single Roman word to Devanagari.
101
- * @param {string} text - Single English word (e.g. "shantanu", "ramesh")
111
+ * @param {string} text - Single English word (e.g. "shantanu", "ramesh", "Jaad", "Daba")
102
112
  * @returns {string} - Devanagari representation
103
113
  */
104
114
  export function phoneticTransliterateWord(text) {
105
- if (!text) return '';
115
+ if (!text) return "";
106
116
  const clean = text.trim();
107
- if (!clean) return '';
117
+ if (!clean) return "";
108
118
 
109
- let res = '';
119
+ let res = "";
110
120
  let i = 0;
111
121
  const n = clean.length;
112
122
 
@@ -122,7 +132,9 @@ export function phoneticTransliterateWord(text) {
122
132
  let matchedVowel = false;
123
133
  if (i === 0 || !/[a-zA-Z]/.test(clean[i - 1])) {
124
134
  for (const v of INDEPENDENT_VOWELS) {
125
- if (clean.substring(i, i + v.en.length).toLowerCase() === v.en.toLowerCase()) {
135
+ const sub = clean.substring(i, i + v.en.length);
136
+ const isMatch = v.caseSensitive ? sub === v.en : sub.toLowerCase() === v.en.toLowerCase();
137
+ if (isMatch) {
126
138
  res += v.mr;
127
139
  i += v.en.length;
128
140
  matchedVowel = true;
@@ -136,8 +148,7 @@ export function phoneticTransliterateWord(text) {
136
148
  let matchedConsonant = false;
137
149
  for (const c of CONSONANTS) {
138
150
  const sub = clean.substring(i, i + c.en.length);
139
- const isCaseSensitive = c.en === 'L' || c.en === 'T' || c.en === 'D' || c.en === 'N';
140
- const isMatch = isCaseSensitive ? sub === c.en : sub.toLowerCase() === c.en.toLowerCase();
151
+ const isMatch = c.caseSensitive ? sub === c.en : sub.toLowerCase() === c.en.toLowerCase();
141
152
 
142
153
  if (isMatch) {
143
154
  res += c.mr;
@@ -148,11 +159,17 @@ export function phoneticTransliterateWord(text) {
148
159
  let matchedMatra = false;
149
160
  for (const m of MATRAS) {
150
161
  const nextSub = clean.substring(i, i + m.en.length);
151
- const mCaseSensitive = m.en === 'A';
162
+ const mCaseSensitive = m.caseSensitive || m.en === "A";
152
163
  const mMatch = mCaseSensitive ? nextSub === m.en : nextSub.toLowerCase() === m.en.toLowerCase();
153
164
 
154
165
  if (mMatch) {
155
- res += m.mr;
166
+ // When user types trailing "a" at the end of word (e.g. daba -> डबा, patrika -> पत्रिका),
167
+ // in casual Marathi it represents the kana "ा"
168
+ if (m.en === "a" && i + 1 === n && i > 0) {
169
+ res += "ा";
170
+ } else {
171
+ res += m.mr;
172
+ }
156
173
  i += m.en.length;
157
174
  matchedMatra = true;
158
175
  break;
@@ -163,7 +180,7 @@ export function phoneticTransliterateWord(text) {
163
180
  // In Marathi/Hindi phonetics, word-final consonants do NOT get halant
164
181
  if (!matchedMatra) {
165
182
  if (i < n && /[a-zA-Z]/.test(clean[i])) {
166
- res += '्';
183
+ res += "्";
167
184
  }
168
185
  }
169
186