turkce-normalize 0.1.0__tar.gz
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.
- turkce_normalize-0.1.0/LICENSE +21 -0
- turkce_normalize-0.1.0/PKG-INFO +333 -0
- turkce_normalize-0.1.0/README.md +313 -0
- turkce_normalize-0.1.0/pyproject.toml +33 -0
- turkce_normalize-0.1.0/setup.cfg +4 -0
- turkce_normalize-0.1.0/tests/test_parite.py +218 -0
- turkce_normalize-0.1.0/tests/test_yeni.py +270 -0
- turkce_normalize-0.1.0/turkce_normalize/__init__.py +48 -0
- turkce_normalize-0.1.0/turkce_normalize/__main__.py +45 -0
- turkce_normalize-0.1.0/turkce_normalize/cografi.py +153 -0
- turkce_normalize-0.1.0/turkce_normalize/cumle.py +110 -0
- turkce_normalize-0.1.0/turkce_normalize/isaretler.py +78 -0
- turkce_normalize-0.1.0/turkce_normalize/normalize.py +633 -0
- turkce_normalize-0.1.0/turkce_normalize/sayilar.py +175 -0
- turkce_normalize-0.1.0/turkce_normalize/telaffuz.py +127 -0
- turkce_normalize-0.1.0/turkce_normalize.egg-info/PKG-INFO +333 -0
- turkce_normalize-0.1.0/turkce_normalize.egg-info/SOURCES.txt +18 -0
- turkce_normalize-0.1.0/turkce_normalize.egg-info/dependency_links.txt +1 -0
- turkce_normalize-0.1.0/turkce_normalize.egg-info/entry_points.txt +2 -0
- turkce_normalize-0.1.0/turkce_normalize.egg-info/top_level.txt +1 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Mehmet Veysel Delibaş
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: turkce-normalize
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: TTS için Türkçe metin normalizasyonu: sayı, tarih, saat, para, kısaltma, Roma rakamı, kesir, e-posta ve adres okunuşu.
|
|
5
|
+
Author: Mehmet Veysel Delibaş
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/seslen-tr/turkce-normalize
|
|
8
|
+
Project-URL: Source, https://github.com/seslen-tr/turkce-normalize
|
|
9
|
+
Project-URL: Issues, https://github.com/seslen-tr/turkce-normalize/issues
|
|
10
|
+
Keywords: türkçe,turkish,tts,text-normalization,normalizasyon,speech
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: Natural Language :: Turkish
|
|
13
|
+
Classifier: Operating System :: OS Independent
|
|
14
|
+
Classifier: Topic :: Multimedia :: Sound/Audio :: Speech
|
|
15
|
+
Classifier: Topic :: Text Processing :: Linguistic
|
|
16
|
+
Requires-Python: >=3.9
|
|
17
|
+
Description-Content-Type: text/markdown
|
|
18
|
+
License-File: LICENSE
|
|
19
|
+
Dynamic: license-file
|
|
20
|
+
|
|
21
|
+
# turkce-normalize
|
|
22
|
+
|
|
23
|
+
> **English:** Turkish text normalization for text-to-speech. Expands numbers, dates, times, currency, abbreviations, Roman numerals, fractions, e-mail and web addresses into how they are read aloud, following Turkish rules (`14:30'da` → `on dört otuzda`). No dependencies, Python 3.9+, includes an abbreviation-aware sentence splitter for streaming LLM output.
|
|
24
|
+
|
|
25
|
+
TTS (metinden sese) modelleri için Türkçe metin normalizasyonu.
|
|
26
|
+
|
|
27
|
+
Chatterbox, XTTS, Piper, StyleTTS2 gibi açık kaynak modeller SSML desteklemez
|
|
28
|
+
ve `1.250,50 ₺`, `14:05`, `XX. yüzyıl`, `TBMM'de` gibi gösterimleri Türkçe
|
|
29
|
+
kurallarına göre okuyamaz. Bu paket metni modele göndermeden önce "okunur"
|
|
30
|
+
hale getirir:
|
|
31
|
+
|
|
32
|
+
```text
|
|
33
|
+
Toplantı 14:30'da, %18 KDV dahil 1.250,50 ₺.
|
|
34
|
+
→ Toplantı on dört otuzda, yüzde on sekiz katma değer vergisi dahil bin iki yüz elli lira elli kuruş.
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
- Bağımlılığı yoktur (yalnızca standart kütüphane), Python 3.9+.
|
|
38
|
+
- Kurallar sıralıdır ve her biri testlerle sabitlenmiştir.
|
|
39
|
+
- Akış halinde gelen LLM çıktısı için kısaltma farkında bir cümle ayırıcı içerir.
|
|
40
|
+
|
|
41
|
+
## Kurulum
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
pip install . # depo kökünde
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Kullanım
|
|
48
|
+
|
|
49
|
+
```python
|
|
50
|
+
from turkce_normalize import normalize
|
|
51
|
+
|
|
52
|
+
normalize("Sözleşme 15.03.2026 tarihinde yenilenecek.")
|
|
53
|
+
# 'Sözleşme on beş mart iki bin yirmi altı tarihinde yenilenecek.'
|
|
54
|
+
|
|
55
|
+
normalize("XX. yüzyılda II. Abdülhamit 1876-1909 arasında hüküm sürdü.")
|
|
56
|
+
# 'yirminci yüzyılda ikinci Abdülhamit bin sekiz yüz yetmiş altı ile bin dokuz yüz dokuz arasında hüküm sürdü.'
|
|
57
|
+
|
|
58
|
+
normalize("TBMM'de TRT ve NATO konuşuldu.")
|
|
59
|
+
# 'te be me mede te re te ve nato konuşuldu.'
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Komut satırından:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
python -m turkce_normalize "Tarifte 1/2 kilo un, 3/4 su bardağı süt var."
|
|
66
|
+
# Tarifte yarım kilo un, dörtte üç su bardağı süt var.
|
|
67
|
+
|
|
68
|
+
echo "3-5 kişilik ekip -5 derecede çalıştı." | python -m turkce_normalize
|
|
69
|
+
# üç beş kişilik ekip eksi beş derecede çalıştı.
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### Seçenekler
|
|
73
|
+
|
|
74
|
+
```python
|
|
75
|
+
normalize(metin,
|
|
76
|
+
telaffuz=None, # telaffuz sözlüğü (varsayılan: gömülü CBS/yazılım sözlüğü)
|
|
77
|
+
cografi=True, # koordinat, ölçek, pafta, EPSG kuralları
|
|
78
|
+
kisaltma_harf_harf=True) # "TBMM" -> "te be me me"
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Sayı okuma
|
|
82
|
+
|
|
83
|
+
```python
|
|
84
|
+
from turkce_normalize import sayi_oku, sira_oku, ondalik_oku, rakamlari_tek_tek
|
|
85
|
+
|
|
86
|
+
sayi_oku(1250) # 'bin iki yüz elli'
|
|
87
|
+
sayi_oku(1_000_000) # 'bir milyon'
|
|
88
|
+
sira_oku(21) # 'yirmi birinci'
|
|
89
|
+
ondalik_oku(3, "05") # 'üç virgül sıfır beş'
|
|
90
|
+
rakamlari_tek_tek("0212") # 'sıfır iki bir iki'
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### Cümle ayırıcı (LLM akışı için)
|
|
94
|
+
|
|
95
|
+
Cevabın tamamı bitmeden ilk cümle seslendirilmeye başlasın diye. `Sn. Dr.`
|
|
96
|
+
gibi kısaltmalarda ve `15.03.2026` gibi tarihlerde bölmez; 12 karakterden
|
|
97
|
+
kısa cümleleri ("Evet.") sonrakiyle birleştirir.
|
|
98
|
+
|
|
99
|
+
```python
|
|
100
|
+
from turkce_normalize import CumleAyirici, cumleleri_ayir
|
|
101
|
+
|
|
102
|
+
ayirici = CumleAyirici()
|
|
103
|
+
for parca in llm_akisi: # token token gelen metin
|
|
104
|
+
for cumle in ayirici.push(parca):
|
|
105
|
+
seslendir(normalize(cumle))
|
|
106
|
+
for cumle in ayirici.flush():
|
|
107
|
+
seslendir(normalize(cumle))
|
|
108
|
+
|
|
109
|
+
cumleleri_ayir("Merhaba. Sn. Dr. Ayşe Yılmaz geldi! Devam edelim mi?")
|
|
110
|
+
# ['Merhaba. Sn. Dr. Ayşe Yılmaz geldi!', 'Devam edelim mi?']
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
`cumle_akisi(iterable)` ve `cumle_akisi_async(async_iterable)` aynı işi
|
|
114
|
+
üreteç olarak yapar.
|
|
115
|
+
|
|
116
|
+
### Duraklama işaretleri
|
|
117
|
+
|
|
118
|
+
SSML olmayan modellerde duraklamayı kendin kurmak için metni `[dur]`
|
|
119
|
+
işaretlerinden böler:
|
|
120
|
+
|
|
121
|
+
```python
|
|
122
|
+
from turkce_normalize import isaretleri_ayir, isaretleri_temizle
|
|
123
|
+
|
|
124
|
+
isaretleri_ayir("Sorgu bitti. [dur:0.8] Toplam 340 hektar.")
|
|
125
|
+
# [Parca(metin='Sorgu bitti.', duraklama=0.8), Parca(metin='Toplam 340 hektar.', duraklama=0)]
|
|
126
|
+
|
|
127
|
+
isaretleri_temizle("Sorgu bitti. [dur:0.8] Toplam.") # altyazı için
|
|
128
|
+
# 'Sorgu bitti. Toplam.'
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
`[dur]` tek başına 0,45 sn'dir; üst sınır 5 sn. Bilinmeyen işaretler
|
|
132
|
+
(`[vurgu]`) bilerek silinmez — model okur, sen hatayı duyarsın.
|
|
133
|
+
|
|
134
|
+
### Telaffuz sözlüğü
|
|
135
|
+
|
|
136
|
+
Gömülü sözlük CBS ve yazılım jargonunu Türk kulağına doğru gelen yazımla
|
|
137
|
+
değiştirir (`shapefile` → `şeypfayl`, `WMS` → `ve me se`, `API` → `ey pi ay`).
|
|
138
|
+
Kendi terimlerini ekleyebilirsin:
|
|
139
|
+
|
|
140
|
+
```python
|
|
141
|
+
from turkce_normalize import normalize, sozluk_birlestir, VARSAYILAN_SOZLUK
|
|
142
|
+
|
|
143
|
+
sozluk = sozluk_birlestir(VARSAYILAN_SOZLUK, {"KENTGIS": "kent cis"})
|
|
144
|
+
normalize("KENTGIS açılıyor.", telaffuz=sozluk) # 'kent cis açılıyor.'
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
Eşleşme büyük/küçük harf duyarsızdır; ek almış kelimeler (`APIyi`) bölünmez.
|
|
148
|
+
|
|
149
|
+
## Desteklenen gösterimler
|
|
150
|
+
|
|
151
|
+
| Gösterim | Örnek | Okunuş |
|
|
152
|
+
|---|---|---|
|
|
153
|
+
| Tam sayı | `1.250` | bin iki yüz elli |
|
|
154
|
+
| Ondalık | `3,5` / `3,05` | üç virgül beş / üç virgül sıfır beş |
|
|
155
|
+
| Sıra sayısı | `3. madde` | üçüncü madde |
|
|
156
|
+
| Para | `1.250,50 ₺`, `2.360 TL` | bin iki yüz elli lira elli kuruş |
|
|
157
|
+
| Yüzde | `%18`, `% 18,5` | yüzde on sekiz |
|
|
158
|
+
| Tarih | `15.03.2026`, `15/03/2026` | on beş mart iki bin yirmi altı |
|
|
159
|
+
| Saat | `14:05`, `09:00'da` | on dört sıfır beş, dokuzda |
|
|
160
|
+
| Telefon | `0212 555 44 33`, `0212-555-44-33` | sıfır iki bir iki beş beş beş … |
|
|
161
|
+
| IBAN | `TR33 0006 …` | te re üç üç sıfır sıfır … |
|
|
162
|
+
| Kısaltma (sözlük) | `KDV`, `Dr.`, `vb.`, `Mah.` | katma değer vergisi, doktor, ve benzeri, mahallesi |
|
|
163
|
+
| Birim | `12 km`, `85 m²`, `5 kg` | on iki kilometre, … metrekare, … kilogram |
|
|
164
|
+
| **Roma rakamı** | `XX. yüzyıl`, `II. Abdülhamit` | yirminci yüzyıl, ikinci Abdülhamit |
|
|
165
|
+
| **Kesir** | `1/2 kilo`, `1/4`, `3/4`, `1/6`, `2 1/2` | yarım kilo, çeyrek, dörtte üç, altıda bir, iki buçuk |
|
|
166
|
+
| **Aralık** | `3-5 kişi`, `2020-2025`, `3-5. maddeler` | üç beş kişi, … ile …, üçüncü ile beşinci |
|
|
167
|
+
| **Eksi sayı** | `-5 derece` | eksi beş derece |
|
|
168
|
+
| **Büyük harfli kısaltma** | `TBMM'de`, `CHP`, `NATO` | te be me mede, ce he pe, nato |
|
|
169
|
+
| **E-posta** | `ali.veli@ornek.com.tr` | ali nokta veli et ornek nokta com nokta te re |
|
|
170
|
+
| **Web adresi** | `https://www.ornek.gov.tr/harita` | ornek nokta gov nokta te re bölü harita |
|
|
171
|
+
| **Simgeler** | `2+2=4`, `&`, `25°C`, `±0,5` | iki artı iki eşittir dört, ve, yirmi beş derece, artı eksi … |
|
|
172
|
+
| Koordinat | `39.9334, 32.8597` | enlem otuz dokuz virgül dokuz üç üç dört, boylam … |
|
|
173
|
+
| Derece-dakika-saniye | `39°56'12"K` | otuz dokuz derece elli altı dakika on iki saniye kuzey |
|
|
174
|
+
| Ölçek | `1/25.000`, `1:1000` | yirmi beş binde bir, binde bir |
|
|
175
|
+
| Pafta kodu | `G22-b-14c-2d` | ge yirmi iki be on dört ce iki de |
|
|
176
|
+
| EPSG / UTM | `EPSG:5254`, `UTM 35N` | e pe es ge beş iki beş dört, u te me otuz beşinci dilim kuzey |
|
|
177
|
+
| Alan birimi | `340 ha`, `12 da` | üç yüz kırk hektar, on iki dekar |
|
|
178
|
+
|
|
179
|
+
Kalın satırlar kaynak projede olmayıp bu pakette eklenenlerdir. Ayrıntıları:
|
|
180
|
+
|
|
181
|
+
### Roma rakamları
|
|
182
|
+
|
|
183
|
+
Yalnızca **ardından nokta gelen** geçerli Roma rakamları (I–MMMM) sıra sayısı
|
|
184
|
+
olarak okunur:
|
|
185
|
+
|
|
186
|
+
- Nokta ve ardından **küçük harfle** başlayan kelime: `XX. yüzyıl` → yirminci yüzyıl.
|
|
187
|
+
- Nokta ve ardından **büyük harfle** başlayan kelime (hükümdar sırası): yalnızca
|
|
188
|
+
I, V, X harflerinden oluşan ve 39'u aşmayan rakamlar: `III. Selim` → üçüncü Selim,
|
|
189
|
+
`I. Dünya Savaşı` → birinci Dünya Savaşı.
|
|
190
|
+
- Tek harfli rakam büyük harfli bir kelimeden sonra geliyorsa isim baş harfi
|
|
191
|
+
sayılır (`Mehmet V. Delibaş` değişmez); `Sultan`, `Kral`, `Papa` gibi
|
|
192
|
+
unvanlar (`UNVANLAR`) istisnadır.
|
|
193
|
+
- `MI`, `CD`, `CM`, `MM`, `DIV` … gibi kelime/kısaltma olabilenler kara
|
|
194
|
+
listededir (`ROMA_KARA_LISTE`).
|
|
195
|
+
|
|
196
|
+
### Kesirler
|
|
197
|
+
|
|
198
|
+
- `1/2` → yarım, `1/4` → çeyrek; ötekiler "payda + bulunma eki + pay":
|
|
199
|
+
`3/4` → dörtte üç, `2/3` → üçte iki, `1/6` → altıda bir, `3/40` → kırkta üç.
|
|
200
|
+
- Bulunma eki ünlü uyumuna ve ünsüz benzeşmesine uyar (`bulunma_eki()`):
|
|
201
|
+
ç, f, h, k, p, s, ş, t'den sonra **te/ta**, diğerlerinde **de/da**.
|
|
202
|
+
- Tam sayılı kesir: `2 1/2` → iki buçuk, `3 3/4` → üç tam dörtte üç; `½ ¼ ¾`
|
|
203
|
+
karakterleri de okunur.
|
|
204
|
+
- Yalnızca **bayağı kesirler** (pay < payda) okunur; `15/03` dokunulmaz. `24/7` → yirmi dört yedi.
|
|
205
|
+
- Ekli kesir: `1/2'si` → yarısı, `1/4'ü` → çeyreği, `3/4'ü` → dörtte üçü.
|
|
206
|
+
- Tarih (`15/03/2026`) ve ölçek (`1/25.000`, `1:1000`) kuralları önce çalışır.
|
|
207
|
+
- Adreste kapı numarası: `No: 5/7` → No: beş bölü yedi.
|
|
208
|
+
|
|
209
|
+
### Aralıklar
|
|
210
|
+
|
|
211
|
+
- İki sayı da 100 veya küçük ve ilki küçükse günlük konuşmadaki gibi:
|
|
212
|
+
`3-5 kişi` → üç beş kişi, `10–20 dakika` → on yirmi dakika.
|
|
213
|
+
- Diğerleri "X ile Y": `2020-2025` → iki bin yirmi ile iki bin yirmi beş,
|
|
214
|
+
`1.000-2.000 TL` → bin ile iki bin lira.
|
|
215
|
+
- Sıra sayısı aralığı: `3-5. maddeler` → üçüncü ile beşinci maddeler.
|
|
216
|
+
- Saat ve tarih aralığı: `14:30-15:30` → on dört otuz ile on beş otuz;
|
|
217
|
+
yüzde aralığı: `%10-20` → yüzde on ile yirmi.
|
|
218
|
+
- İlki büyük ya da eşitse skor gibi okunur: `3-1` → üç bir. Sıfırla başlıyorsa (kod)
|
|
219
|
+
veya ikiden fazla sayı tireyle bağlıysa (`0212-555-44-33`) aralık sayılmaz.
|
|
220
|
+
- Önünde harf/rakam olmayan tire eksi işaretidir: `-5 derece` → eksi beş derece.
|
|
221
|
+
|
|
222
|
+
### Büyük harfli kısaltmalar
|
|
223
|
+
|
|
224
|
+
- 2–5 büyük harften oluşan tokenlar Türkçe harf adlarıyla okunur:
|
|
225
|
+
`TBMM` → te be me me, `AKP` → a ka pe. Harf adları: a, be, ce, çe, de, e, fe,
|
|
226
|
+
ge, yumuşak ge, he, ı, i, je, ka, le, me, ne, o, ö, pe, re, se, şe, te, u, ü,
|
|
227
|
+
ve, ye, ze; Q kü, W çift ve, X iks. K kısaltmalardaki yaygın okunuşla "ka"dır
|
|
228
|
+
(TDK alfabesinde "ke"); `HARF_OKUNUSU["K"] = "ke"` ile değiştirilebilir.
|
|
229
|
+
- Kesmeden sonraki ek okunuşa bitişir: `TBMM'de` → te be me mede,
|
|
230
|
+
`ABD'li` → a be deli.
|
|
231
|
+
- Kelime gibi okunan kısaltmalar (`KELIME_GIBI_OKUNANLAR`) harf harf okunmaz,
|
|
232
|
+
modelin hecelememesi için küçük harfe çevrilir: NATO, NASA, AFAD, TOKİ,
|
|
233
|
+
BOTAŞ, TEDAŞ, İSKİ, ASKİ, ODTÜ, YÖK, TÜİK, İŞKUR, MİT, ASELSAN, TÜBİTAK,
|
|
234
|
+
HAVELSAN, ROKETSAN, KOSGEB, UNESCO, UNICEF … `ÖSYM`, `SGK`, `İETT`, `PTT`
|
|
235
|
+
harf harf okunur.
|
|
236
|
+
- Büyük harfle yazılmış sıradan kelimeler (`UYARI`, `VE`, `MI` …,
|
|
237
|
+
`BILINEN_KELIMELER`) ve bunların komşusu olan büyük harfli kelimeler
|
|
238
|
+
(`GELDİ MI`) kısaltma sayılmaz. 6+ harfli tokenlar ve yalnızca I/V/X'ten
|
|
239
|
+
oluşanlar (Roma rakamı) dokunulmaz.
|
|
240
|
+
- Sözlükteki kısaltmalar (`KDV`, `TL`, `IBAN` …) önce gelir.
|
|
241
|
+
- Listeler genişletilebilir kümelerdir:
|
|
242
|
+
|
|
243
|
+
```python
|
|
244
|
+
from turkce_normalize import KELIME_GIBI_OKUNANLAR, BILINEN_KELIMELER
|
|
245
|
+
KELIME_GIBI_OKUNANLAR.add("TEKNOFEST")
|
|
246
|
+
BILINEN_KELIMELER.add("KAMPANYA")
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
### E-posta ve web adresi
|
|
250
|
+
|
|
251
|
+
- `@` → et, `.` → nokta, `/` → bölü, `-` → tire, `_` → alt çizgi.
|
|
252
|
+
- `http(s)://` ve `www.` atılır; sorgu (`?…`) ve çapa (`#…`) okunmaz.
|
|
253
|
+
- Son etiket iki harfli ülke uzantısıysa harf harf okunur (`tr` → te re);
|
|
254
|
+
`com`, `gov`, `org` yazıldığı gibi kalır.
|
|
255
|
+
- Şemasız alan adları yalnızca küçük harfle ve bilinen bir uzantıyla
|
|
256
|
+
(`com`, `net`, `org`, `gov`, `edu`, `tr`, `io` …) yazılmışsa yakalanır.
|
|
257
|
+
- Adres parçaları sonra telaffuz sözlüğünden geçer: `rapor.pdf` → rapor nokta pe de fe.
|
|
258
|
+
|
|
259
|
+
### Simgeler
|
|
260
|
+
|
|
261
|
+
`&` → ve; `+` iki sayı arasında → artı (`+90` gibi önekler dokunulmaz);
|
|
262
|
+
`=` → eşittir; `°C` / `℃` → derece; `°F` → derece fahrenhayt;
|
|
263
|
+
sayıdan sonra `°` → derece; `±` → artı eksi.
|
|
264
|
+
|
|
265
|
+
## Kural sırası
|
|
266
|
+
|
|
267
|
+
Sıra rastgele değildir; bütün bir birim olan gösterimler sayı kurallarından
|
|
268
|
+
önce gelir, yoksa içlerindeki rakamlar genel kurallara yem olur:
|
|
269
|
+
|
|
270
|
+
1. e-posta ve web adresi → 2. sıcaklık → 3. coğrafi gösterimler →
|
|
271
|
+
4. telaffuz sözlüğü → 5. IBAN → 6. telefon → 7. tarih ve saat (ISO ve tireli tarih dahil) →
|
|
272
|
+
8. simgeler → 9. kesirler → 10. aralıklar → 11. eksi sayılar → 12. para →
|
|
273
|
+
13. yüzde → 14. kısaltmalar ve birimler → 15. Roma rakamları →
|
|
274
|
+
16. büyük harfli kısaltmalar → 17. sıra sayıları → 18. ondalık →
|
|
275
|
+
19. tam sayılar → 20. kesme işaretinin kaldırılması
|
|
276
|
+
|
|
277
|
+
## Sınırlamalar
|
|
278
|
+
|
|
279
|
+
- Ek uyumu yapılmaz: `5'te` → beşte doğru çıkar çünkü ek zaten okunuşa göre
|
|
280
|
+
yazılmıştır; ama yanlış yazılmış ekler düzeltilmez.
|
|
281
|
+
- Nokta, ardından tam üç rakam geliyorsa binlik ayırıcıdır (`3.500` → üç bin beş yüz);
|
|
282
|
+
aksi halde İngilizce usulü ondalık sayılır (`3.5` → üç virgül beş). Üç ve daha fazla
|
|
283
|
+
noktalı grupta üç rakamlı olmayan grup varsa sürüm numarasıdır (`1.2.3` → bir nokta iki
|
|
284
|
+
nokta üç). Noktalı saat yalnız "saat" sözcüğünden sonra tanınır (`saat 14.30`).
|
|
285
|
+
- Sıra sayısı ve Roma rakamı için ardından bir kelime gelmesi gerekir; cümle
|
|
286
|
+
sonundaki `XIV.` dokunulmaz.
|
|
287
|
+
- Cümle başındaki büyük harf, dönüştürülen kelimeyle birlikte kaybolur
|
|
288
|
+
(`XX. yüzyıl` → yirminci yüzyıl).
|
|
289
|
+
- Büyük harfli kısaltma tespiti sezgiseldir: listede olmayan 2–5 harfli büyük
|
|
290
|
+
harfli sıradan kelimeler harf harf okunabilir; tamamı büyük harfle yazılmış
|
|
291
|
+
metinlerde `kisaltma_harf_harf=False` kullanın. Tek harfli Roma rakamı bir
|
|
292
|
+
ismin baş harfiyle karışabilir (`romanı V. Hugo yazdı`).
|
|
293
|
+
- Tam sayılı ekli kesir (`2 1/2'si`) düzeltilmez.
|
|
294
|
+
- Şemasız alan adlarında Türkçe karakter (IDN) desteklenmez.
|
|
295
|
+
- İngilizce normalizasyon kapsam dışıdır; metin Türkçe kabul edilir.
|
|
296
|
+
|
|
297
|
+
## Testler
|
|
298
|
+
|
|
299
|
+
```bash
|
|
300
|
+
python -m unittest discover -s tests
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
`tests/test_parite.py` kaynak TypeScript projesindeki testlerin birebir
|
|
304
|
+
karşılığıdır (beklenen çıktılar aynı); `tests/test_yeni.py` bu pakette
|
|
305
|
+
eklenen özellikleri ve yanlış pozitifleri sabitler.
|
|
306
|
+
|
|
307
|
+
## Lisans
|
|
308
|
+
|
|
309
|
+
MIT — bkz. [LICENSE](LICENSE).
|
|
310
|
+
|
|
311
|
+
---
|
|
312
|
+
|
|
313
|
+
## English summary
|
|
314
|
+
|
|
315
|
+
**turkce-normalize** is a dependency-free Python (3.9+) text normalizer that
|
|
316
|
+
prepares Turkish text for TTS engines without SSML support (Chatterbox, XTTS,
|
|
317
|
+
Piper, StyleTTS2…). It spells out numbers, ordinals, decimals, money, percent,
|
|
318
|
+
dates, times, phone numbers, IBANs, abbreviations and units; Roman numerals
|
|
319
|
+
(`XX. yüzyıl` → "yirminci yüzyıl"), fractions with correct vowel harmony
|
|
320
|
+
(`3/4` → "dörtte üç"), numeric ranges, negative numbers, all-caps acronyms read
|
|
321
|
+
letter by letter with Turkish letter names (`TBMM'de` → "te be me mede", with a
|
|
322
|
+
configurable list of acronyms read as words such as NATO, TÜBİTAK), e-mail
|
|
323
|
+
addresses and URLs, common symbols, and GIS notation (coordinates, map scale,
|
|
324
|
+
sheet codes, EPSG/UTM). It also ships an abbreviation-aware streaming sentence
|
|
325
|
+
splitter for LLM output and an inline pause-marker parser (`[dur:0.8]`).
|
|
326
|
+
|
|
327
|
+
```python
|
|
328
|
+
from turkce_normalize import normalize
|
|
329
|
+
normalize("Toplantı 14:30'da, %18 KDV dahil 1.250,50 ₺.")
|
|
330
|
+
# 'Toplantı on dört otuzda, yüzde on sekiz katma değer vergisi dahil bin iki yüz elli lira elli kuruş.'
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
CLI: `python -m turkce_normalize "metin"`. Tests: `python -m unittest discover -s tests`. License: MIT.
|
|
@@ -0,0 +1,313 @@
|
|
|
1
|
+
# turkce-normalize
|
|
2
|
+
|
|
3
|
+
> **English:** Turkish text normalization for text-to-speech. Expands numbers, dates, times, currency, abbreviations, Roman numerals, fractions, e-mail and web addresses into how they are read aloud, following Turkish rules (`14:30'da` → `on dört otuzda`). No dependencies, Python 3.9+, includes an abbreviation-aware sentence splitter for streaming LLM output.
|
|
4
|
+
|
|
5
|
+
TTS (metinden sese) modelleri için Türkçe metin normalizasyonu.
|
|
6
|
+
|
|
7
|
+
Chatterbox, XTTS, Piper, StyleTTS2 gibi açık kaynak modeller SSML desteklemez
|
|
8
|
+
ve `1.250,50 ₺`, `14:05`, `XX. yüzyıl`, `TBMM'de` gibi gösterimleri Türkçe
|
|
9
|
+
kurallarına göre okuyamaz. Bu paket metni modele göndermeden önce "okunur"
|
|
10
|
+
hale getirir:
|
|
11
|
+
|
|
12
|
+
```text
|
|
13
|
+
Toplantı 14:30'da, %18 KDV dahil 1.250,50 ₺.
|
|
14
|
+
→ Toplantı on dört otuzda, yüzde on sekiz katma değer vergisi dahil bin iki yüz elli lira elli kuruş.
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
- Bağımlılığı yoktur (yalnızca standart kütüphane), Python 3.9+.
|
|
18
|
+
- Kurallar sıralıdır ve her biri testlerle sabitlenmiştir.
|
|
19
|
+
- Akış halinde gelen LLM çıktısı için kısaltma farkında bir cümle ayırıcı içerir.
|
|
20
|
+
|
|
21
|
+
## Kurulum
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
pip install . # depo kökünde
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Kullanım
|
|
28
|
+
|
|
29
|
+
```python
|
|
30
|
+
from turkce_normalize import normalize
|
|
31
|
+
|
|
32
|
+
normalize("Sözleşme 15.03.2026 tarihinde yenilenecek.")
|
|
33
|
+
# 'Sözleşme on beş mart iki bin yirmi altı tarihinde yenilenecek.'
|
|
34
|
+
|
|
35
|
+
normalize("XX. yüzyılda II. Abdülhamit 1876-1909 arasında hüküm sürdü.")
|
|
36
|
+
# 'yirminci yüzyılda ikinci Abdülhamit bin sekiz yüz yetmiş altı ile bin dokuz yüz dokuz arasında hüküm sürdü.'
|
|
37
|
+
|
|
38
|
+
normalize("TBMM'de TRT ve NATO konuşuldu.")
|
|
39
|
+
# 'te be me mede te re te ve nato konuşuldu.'
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Komut satırından:
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
python -m turkce_normalize "Tarifte 1/2 kilo un, 3/4 su bardağı süt var."
|
|
46
|
+
# Tarifte yarım kilo un, dörtte üç su bardağı süt var.
|
|
47
|
+
|
|
48
|
+
echo "3-5 kişilik ekip -5 derecede çalıştı." | python -m turkce_normalize
|
|
49
|
+
# üç beş kişilik ekip eksi beş derecede çalıştı.
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### Seçenekler
|
|
53
|
+
|
|
54
|
+
```python
|
|
55
|
+
normalize(metin,
|
|
56
|
+
telaffuz=None, # telaffuz sözlüğü (varsayılan: gömülü CBS/yazılım sözlüğü)
|
|
57
|
+
cografi=True, # koordinat, ölçek, pafta, EPSG kuralları
|
|
58
|
+
kisaltma_harf_harf=True) # "TBMM" -> "te be me me"
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Sayı okuma
|
|
62
|
+
|
|
63
|
+
```python
|
|
64
|
+
from turkce_normalize import sayi_oku, sira_oku, ondalik_oku, rakamlari_tek_tek
|
|
65
|
+
|
|
66
|
+
sayi_oku(1250) # 'bin iki yüz elli'
|
|
67
|
+
sayi_oku(1_000_000) # 'bir milyon'
|
|
68
|
+
sira_oku(21) # 'yirmi birinci'
|
|
69
|
+
ondalik_oku(3, "05") # 'üç virgül sıfır beş'
|
|
70
|
+
rakamlari_tek_tek("0212") # 'sıfır iki bir iki'
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Cümle ayırıcı (LLM akışı için)
|
|
74
|
+
|
|
75
|
+
Cevabın tamamı bitmeden ilk cümle seslendirilmeye başlasın diye. `Sn. Dr.`
|
|
76
|
+
gibi kısaltmalarda ve `15.03.2026` gibi tarihlerde bölmez; 12 karakterden
|
|
77
|
+
kısa cümleleri ("Evet.") sonrakiyle birleştirir.
|
|
78
|
+
|
|
79
|
+
```python
|
|
80
|
+
from turkce_normalize import CumleAyirici, cumleleri_ayir
|
|
81
|
+
|
|
82
|
+
ayirici = CumleAyirici()
|
|
83
|
+
for parca in llm_akisi: # token token gelen metin
|
|
84
|
+
for cumle in ayirici.push(parca):
|
|
85
|
+
seslendir(normalize(cumle))
|
|
86
|
+
for cumle in ayirici.flush():
|
|
87
|
+
seslendir(normalize(cumle))
|
|
88
|
+
|
|
89
|
+
cumleleri_ayir("Merhaba. Sn. Dr. Ayşe Yılmaz geldi! Devam edelim mi?")
|
|
90
|
+
# ['Merhaba. Sn. Dr. Ayşe Yılmaz geldi!', 'Devam edelim mi?']
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
`cumle_akisi(iterable)` ve `cumle_akisi_async(async_iterable)` aynı işi
|
|
94
|
+
üreteç olarak yapar.
|
|
95
|
+
|
|
96
|
+
### Duraklama işaretleri
|
|
97
|
+
|
|
98
|
+
SSML olmayan modellerde duraklamayı kendin kurmak için metni `[dur]`
|
|
99
|
+
işaretlerinden böler:
|
|
100
|
+
|
|
101
|
+
```python
|
|
102
|
+
from turkce_normalize import isaretleri_ayir, isaretleri_temizle
|
|
103
|
+
|
|
104
|
+
isaretleri_ayir("Sorgu bitti. [dur:0.8] Toplam 340 hektar.")
|
|
105
|
+
# [Parca(metin='Sorgu bitti.', duraklama=0.8), Parca(metin='Toplam 340 hektar.', duraklama=0)]
|
|
106
|
+
|
|
107
|
+
isaretleri_temizle("Sorgu bitti. [dur:0.8] Toplam.") # altyazı için
|
|
108
|
+
# 'Sorgu bitti. Toplam.'
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
`[dur]` tek başına 0,45 sn'dir; üst sınır 5 sn. Bilinmeyen işaretler
|
|
112
|
+
(`[vurgu]`) bilerek silinmez — model okur, sen hatayı duyarsın.
|
|
113
|
+
|
|
114
|
+
### Telaffuz sözlüğü
|
|
115
|
+
|
|
116
|
+
Gömülü sözlük CBS ve yazılım jargonunu Türk kulağına doğru gelen yazımla
|
|
117
|
+
değiştirir (`shapefile` → `şeypfayl`, `WMS` → `ve me se`, `API` → `ey pi ay`).
|
|
118
|
+
Kendi terimlerini ekleyebilirsin:
|
|
119
|
+
|
|
120
|
+
```python
|
|
121
|
+
from turkce_normalize import normalize, sozluk_birlestir, VARSAYILAN_SOZLUK
|
|
122
|
+
|
|
123
|
+
sozluk = sozluk_birlestir(VARSAYILAN_SOZLUK, {"KENTGIS": "kent cis"})
|
|
124
|
+
normalize("KENTGIS açılıyor.", telaffuz=sozluk) # 'kent cis açılıyor.'
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
Eşleşme büyük/küçük harf duyarsızdır; ek almış kelimeler (`APIyi`) bölünmez.
|
|
128
|
+
|
|
129
|
+
## Desteklenen gösterimler
|
|
130
|
+
|
|
131
|
+
| Gösterim | Örnek | Okunuş |
|
|
132
|
+
|---|---|---|
|
|
133
|
+
| Tam sayı | `1.250` | bin iki yüz elli |
|
|
134
|
+
| Ondalık | `3,5` / `3,05` | üç virgül beş / üç virgül sıfır beş |
|
|
135
|
+
| Sıra sayısı | `3. madde` | üçüncü madde |
|
|
136
|
+
| Para | `1.250,50 ₺`, `2.360 TL` | bin iki yüz elli lira elli kuruş |
|
|
137
|
+
| Yüzde | `%18`, `% 18,5` | yüzde on sekiz |
|
|
138
|
+
| Tarih | `15.03.2026`, `15/03/2026` | on beş mart iki bin yirmi altı |
|
|
139
|
+
| Saat | `14:05`, `09:00'da` | on dört sıfır beş, dokuzda |
|
|
140
|
+
| Telefon | `0212 555 44 33`, `0212-555-44-33` | sıfır iki bir iki beş beş beş … |
|
|
141
|
+
| IBAN | `TR33 0006 …` | te re üç üç sıfır sıfır … |
|
|
142
|
+
| Kısaltma (sözlük) | `KDV`, `Dr.`, `vb.`, `Mah.` | katma değer vergisi, doktor, ve benzeri, mahallesi |
|
|
143
|
+
| Birim | `12 km`, `85 m²`, `5 kg` | on iki kilometre, … metrekare, … kilogram |
|
|
144
|
+
| **Roma rakamı** | `XX. yüzyıl`, `II. Abdülhamit` | yirminci yüzyıl, ikinci Abdülhamit |
|
|
145
|
+
| **Kesir** | `1/2 kilo`, `1/4`, `3/4`, `1/6`, `2 1/2` | yarım kilo, çeyrek, dörtte üç, altıda bir, iki buçuk |
|
|
146
|
+
| **Aralık** | `3-5 kişi`, `2020-2025`, `3-5. maddeler` | üç beş kişi, … ile …, üçüncü ile beşinci |
|
|
147
|
+
| **Eksi sayı** | `-5 derece` | eksi beş derece |
|
|
148
|
+
| **Büyük harfli kısaltma** | `TBMM'de`, `CHP`, `NATO` | te be me mede, ce he pe, nato |
|
|
149
|
+
| **E-posta** | `ali.veli@ornek.com.tr` | ali nokta veli et ornek nokta com nokta te re |
|
|
150
|
+
| **Web adresi** | `https://www.ornek.gov.tr/harita` | ornek nokta gov nokta te re bölü harita |
|
|
151
|
+
| **Simgeler** | `2+2=4`, `&`, `25°C`, `±0,5` | iki artı iki eşittir dört, ve, yirmi beş derece, artı eksi … |
|
|
152
|
+
| Koordinat | `39.9334, 32.8597` | enlem otuz dokuz virgül dokuz üç üç dört, boylam … |
|
|
153
|
+
| Derece-dakika-saniye | `39°56'12"K` | otuz dokuz derece elli altı dakika on iki saniye kuzey |
|
|
154
|
+
| Ölçek | `1/25.000`, `1:1000` | yirmi beş binde bir, binde bir |
|
|
155
|
+
| Pafta kodu | `G22-b-14c-2d` | ge yirmi iki be on dört ce iki de |
|
|
156
|
+
| EPSG / UTM | `EPSG:5254`, `UTM 35N` | e pe es ge beş iki beş dört, u te me otuz beşinci dilim kuzey |
|
|
157
|
+
| Alan birimi | `340 ha`, `12 da` | üç yüz kırk hektar, on iki dekar |
|
|
158
|
+
|
|
159
|
+
Kalın satırlar kaynak projede olmayıp bu pakette eklenenlerdir. Ayrıntıları:
|
|
160
|
+
|
|
161
|
+
### Roma rakamları
|
|
162
|
+
|
|
163
|
+
Yalnızca **ardından nokta gelen** geçerli Roma rakamları (I–MMMM) sıra sayısı
|
|
164
|
+
olarak okunur:
|
|
165
|
+
|
|
166
|
+
- Nokta ve ardından **küçük harfle** başlayan kelime: `XX. yüzyıl` → yirminci yüzyıl.
|
|
167
|
+
- Nokta ve ardından **büyük harfle** başlayan kelime (hükümdar sırası): yalnızca
|
|
168
|
+
I, V, X harflerinden oluşan ve 39'u aşmayan rakamlar: `III. Selim` → üçüncü Selim,
|
|
169
|
+
`I. Dünya Savaşı` → birinci Dünya Savaşı.
|
|
170
|
+
- Tek harfli rakam büyük harfli bir kelimeden sonra geliyorsa isim baş harfi
|
|
171
|
+
sayılır (`Mehmet V. Delibaş` değişmez); `Sultan`, `Kral`, `Papa` gibi
|
|
172
|
+
unvanlar (`UNVANLAR`) istisnadır.
|
|
173
|
+
- `MI`, `CD`, `CM`, `MM`, `DIV` … gibi kelime/kısaltma olabilenler kara
|
|
174
|
+
listededir (`ROMA_KARA_LISTE`).
|
|
175
|
+
|
|
176
|
+
### Kesirler
|
|
177
|
+
|
|
178
|
+
- `1/2` → yarım, `1/4` → çeyrek; ötekiler "payda + bulunma eki + pay":
|
|
179
|
+
`3/4` → dörtte üç, `2/3` → üçte iki, `1/6` → altıda bir, `3/40` → kırkta üç.
|
|
180
|
+
- Bulunma eki ünlü uyumuna ve ünsüz benzeşmesine uyar (`bulunma_eki()`):
|
|
181
|
+
ç, f, h, k, p, s, ş, t'den sonra **te/ta**, diğerlerinde **de/da**.
|
|
182
|
+
- Tam sayılı kesir: `2 1/2` → iki buçuk, `3 3/4` → üç tam dörtte üç; `½ ¼ ¾`
|
|
183
|
+
karakterleri de okunur.
|
|
184
|
+
- Yalnızca **bayağı kesirler** (pay < payda) okunur; `15/03` dokunulmaz. `24/7` → yirmi dört yedi.
|
|
185
|
+
- Ekli kesir: `1/2'si` → yarısı, `1/4'ü` → çeyreği, `3/4'ü` → dörtte üçü.
|
|
186
|
+
- Tarih (`15/03/2026`) ve ölçek (`1/25.000`, `1:1000`) kuralları önce çalışır.
|
|
187
|
+
- Adreste kapı numarası: `No: 5/7` → No: beş bölü yedi.
|
|
188
|
+
|
|
189
|
+
### Aralıklar
|
|
190
|
+
|
|
191
|
+
- İki sayı da 100 veya küçük ve ilki küçükse günlük konuşmadaki gibi:
|
|
192
|
+
`3-5 kişi` → üç beş kişi, `10–20 dakika` → on yirmi dakika.
|
|
193
|
+
- Diğerleri "X ile Y": `2020-2025` → iki bin yirmi ile iki bin yirmi beş,
|
|
194
|
+
`1.000-2.000 TL` → bin ile iki bin lira.
|
|
195
|
+
- Sıra sayısı aralığı: `3-5. maddeler` → üçüncü ile beşinci maddeler.
|
|
196
|
+
- Saat ve tarih aralığı: `14:30-15:30` → on dört otuz ile on beş otuz;
|
|
197
|
+
yüzde aralığı: `%10-20` → yüzde on ile yirmi.
|
|
198
|
+
- İlki büyük ya da eşitse skor gibi okunur: `3-1` → üç bir. Sıfırla başlıyorsa (kod)
|
|
199
|
+
veya ikiden fazla sayı tireyle bağlıysa (`0212-555-44-33`) aralık sayılmaz.
|
|
200
|
+
- Önünde harf/rakam olmayan tire eksi işaretidir: `-5 derece` → eksi beş derece.
|
|
201
|
+
|
|
202
|
+
### Büyük harfli kısaltmalar
|
|
203
|
+
|
|
204
|
+
- 2–5 büyük harften oluşan tokenlar Türkçe harf adlarıyla okunur:
|
|
205
|
+
`TBMM` → te be me me, `AKP` → a ka pe. Harf adları: a, be, ce, çe, de, e, fe,
|
|
206
|
+
ge, yumuşak ge, he, ı, i, je, ka, le, me, ne, o, ö, pe, re, se, şe, te, u, ü,
|
|
207
|
+
ve, ye, ze; Q kü, W çift ve, X iks. K kısaltmalardaki yaygın okunuşla "ka"dır
|
|
208
|
+
(TDK alfabesinde "ke"); `HARF_OKUNUSU["K"] = "ke"` ile değiştirilebilir.
|
|
209
|
+
- Kesmeden sonraki ek okunuşa bitişir: `TBMM'de` → te be me mede,
|
|
210
|
+
`ABD'li` → a be deli.
|
|
211
|
+
- Kelime gibi okunan kısaltmalar (`KELIME_GIBI_OKUNANLAR`) harf harf okunmaz,
|
|
212
|
+
modelin hecelememesi için küçük harfe çevrilir: NATO, NASA, AFAD, TOKİ,
|
|
213
|
+
BOTAŞ, TEDAŞ, İSKİ, ASKİ, ODTÜ, YÖK, TÜİK, İŞKUR, MİT, ASELSAN, TÜBİTAK,
|
|
214
|
+
HAVELSAN, ROKETSAN, KOSGEB, UNESCO, UNICEF … `ÖSYM`, `SGK`, `İETT`, `PTT`
|
|
215
|
+
harf harf okunur.
|
|
216
|
+
- Büyük harfle yazılmış sıradan kelimeler (`UYARI`, `VE`, `MI` …,
|
|
217
|
+
`BILINEN_KELIMELER`) ve bunların komşusu olan büyük harfli kelimeler
|
|
218
|
+
(`GELDİ MI`) kısaltma sayılmaz. 6+ harfli tokenlar ve yalnızca I/V/X'ten
|
|
219
|
+
oluşanlar (Roma rakamı) dokunulmaz.
|
|
220
|
+
- Sözlükteki kısaltmalar (`KDV`, `TL`, `IBAN` …) önce gelir.
|
|
221
|
+
- Listeler genişletilebilir kümelerdir:
|
|
222
|
+
|
|
223
|
+
```python
|
|
224
|
+
from turkce_normalize import KELIME_GIBI_OKUNANLAR, BILINEN_KELIMELER
|
|
225
|
+
KELIME_GIBI_OKUNANLAR.add("TEKNOFEST")
|
|
226
|
+
BILINEN_KELIMELER.add("KAMPANYA")
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
### E-posta ve web adresi
|
|
230
|
+
|
|
231
|
+
- `@` → et, `.` → nokta, `/` → bölü, `-` → tire, `_` → alt çizgi.
|
|
232
|
+
- `http(s)://` ve `www.` atılır; sorgu (`?…`) ve çapa (`#…`) okunmaz.
|
|
233
|
+
- Son etiket iki harfli ülke uzantısıysa harf harf okunur (`tr` → te re);
|
|
234
|
+
`com`, `gov`, `org` yazıldığı gibi kalır.
|
|
235
|
+
- Şemasız alan adları yalnızca küçük harfle ve bilinen bir uzantıyla
|
|
236
|
+
(`com`, `net`, `org`, `gov`, `edu`, `tr`, `io` …) yazılmışsa yakalanır.
|
|
237
|
+
- Adres parçaları sonra telaffuz sözlüğünden geçer: `rapor.pdf` → rapor nokta pe de fe.
|
|
238
|
+
|
|
239
|
+
### Simgeler
|
|
240
|
+
|
|
241
|
+
`&` → ve; `+` iki sayı arasında → artı (`+90` gibi önekler dokunulmaz);
|
|
242
|
+
`=` → eşittir; `°C` / `℃` → derece; `°F` → derece fahrenhayt;
|
|
243
|
+
sayıdan sonra `°` → derece; `±` → artı eksi.
|
|
244
|
+
|
|
245
|
+
## Kural sırası
|
|
246
|
+
|
|
247
|
+
Sıra rastgele değildir; bütün bir birim olan gösterimler sayı kurallarından
|
|
248
|
+
önce gelir, yoksa içlerindeki rakamlar genel kurallara yem olur:
|
|
249
|
+
|
|
250
|
+
1. e-posta ve web adresi → 2. sıcaklık → 3. coğrafi gösterimler →
|
|
251
|
+
4. telaffuz sözlüğü → 5. IBAN → 6. telefon → 7. tarih ve saat (ISO ve tireli tarih dahil) →
|
|
252
|
+
8. simgeler → 9. kesirler → 10. aralıklar → 11. eksi sayılar → 12. para →
|
|
253
|
+
13. yüzde → 14. kısaltmalar ve birimler → 15. Roma rakamları →
|
|
254
|
+
16. büyük harfli kısaltmalar → 17. sıra sayıları → 18. ondalık →
|
|
255
|
+
19. tam sayılar → 20. kesme işaretinin kaldırılması
|
|
256
|
+
|
|
257
|
+
## Sınırlamalar
|
|
258
|
+
|
|
259
|
+
- Ek uyumu yapılmaz: `5'te` → beşte doğru çıkar çünkü ek zaten okunuşa göre
|
|
260
|
+
yazılmıştır; ama yanlış yazılmış ekler düzeltilmez.
|
|
261
|
+
- Nokta, ardından tam üç rakam geliyorsa binlik ayırıcıdır (`3.500` → üç bin beş yüz);
|
|
262
|
+
aksi halde İngilizce usulü ondalık sayılır (`3.5` → üç virgül beş). Üç ve daha fazla
|
|
263
|
+
noktalı grupta üç rakamlı olmayan grup varsa sürüm numarasıdır (`1.2.3` → bir nokta iki
|
|
264
|
+
nokta üç). Noktalı saat yalnız "saat" sözcüğünden sonra tanınır (`saat 14.30`).
|
|
265
|
+
- Sıra sayısı ve Roma rakamı için ardından bir kelime gelmesi gerekir; cümle
|
|
266
|
+
sonundaki `XIV.` dokunulmaz.
|
|
267
|
+
- Cümle başındaki büyük harf, dönüştürülen kelimeyle birlikte kaybolur
|
|
268
|
+
(`XX. yüzyıl` → yirminci yüzyıl).
|
|
269
|
+
- Büyük harfli kısaltma tespiti sezgiseldir: listede olmayan 2–5 harfli büyük
|
|
270
|
+
harfli sıradan kelimeler harf harf okunabilir; tamamı büyük harfle yazılmış
|
|
271
|
+
metinlerde `kisaltma_harf_harf=False` kullanın. Tek harfli Roma rakamı bir
|
|
272
|
+
ismin baş harfiyle karışabilir (`romanı V. Hugo yazdı`).
|
|
273
|
+
- Tam sayılı ekli kesir (`2 1/2'si`) düzeltilmez.
|
|
274
|
+
- Şemasız alan adlarında Türkçe karakter (IDN) desteklenmez.
|
|
275
|
+
- İngilizce normalizasyon kapsam dışıdır; metin Türkçe kabul edilir.
|
|
276
|
+
|
|
277
|
+
## Testler
|
|
278
|
+
|
|
279
|
+
```bash
|
|
280
|
+
python -m unittest discover -s tests
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
`tests/test_parite.py` kaynak TypeScript projesindeki testlerin birebir
|
|
284
|
+
karşılığıdır (beklenen çıktılar aynı); `tests/test_yeni.py` bu pakette
|
|
285
|
+
eklenen özellikleri ve yanlış pozitifleri sabitler.
|
|
286
|
+
|
|
287
|
+
## Lisans
|
|
288
|
+
|
|
289
|
+
MIT — bkz. [LICENSE](LICENSE).
|
|
290
|
+
|
|
291
|
+
---
|
|
292
|
+
|
|
293
|
+
## English summary
|
|
294
|
+
|
|
295
|
+
**turkce-normalize** is a dependency-free Python (3.9+) text normalizer that
|
|
296
|
+
prepares Turkish text for TTS engines without SSML support (Chatterbox, XTTS,
|
|
297
|
+
Piper, StyleTTS2…). It spells out numbers, ordinals, decimals, money, percent,
|
|
298
|
+
dates, times, phone numbers, IBANs, abbreviations and units; Roman numerals
|
|
299
|
+
(`XX. yüzyıl` → "yirminci yüzyıl"), fractions with correct vowel harmony
|
|
300
|
+
(`3/4` → "dörtte üç"), numeric ranges, negative numbers, all-caps acronyms read
|
|
301
|
+
letter by letter with Turkish letter names (`TBMM'de` → "te be me mede", with a
|
|
302
|
+
configurable list of acronyms read as words such as NATO, TÜBİTAK), e-mail
|
|
303
|
+
addresses and URLs, common symbols, and GIS notation (coordinates, map scale,
|
|
304
|
+
sheet codes, EPSG/UTM). It also ships an abbreviation-aware streaming sentence
|
|
305
|
+
splitter for LLM output and an inline pause-marker parser (`[dur:0.8]`).
|
|
306
|
+
|
|
307
|
+
```python
|
|
308
|
+
from turkce_normalize import normalize
|
|
309
|
+
normalize("Toplantı 14:30'da, %18 KDV dahil 1.250,50 ₺.")
|
|
310
|
+
# 'Toplantı on dört otuzda, yüzde on sekiz katma değer vergisi dahil bin iki yüz elli lira elli kuruş.'
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
CLI: `python -m turkce_normalize "metin"`. Tests: `python -m unittest discover -s tests`. License: MIT.
|