tdk-api-wrapper 1.5.0 → 1.5.1
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/dist/{chunk-7KJHYRJZ.mjs → chunk-NEC5MIQM.mjs} +311 -12
- package/dist/cli.js +316 -13
- package/dist/cli.mjs +6 -2
- package/dist/index.js +311 -12
- package/dist/index.mjs +1 -1
- package/package.json +1 -1
- package/src/cli.ts +6 -1
- package/src/morphology.ts +9 -0
- package/src/tdk.ts +344 -37
- package/test/proofread.test.js +28 -0
|
@@ -535,6 +535,13 @@ function getStemCandidates(word, minStemLength = 2, maxDepth = 4) {
|
|
|
535
535
|
seen.add(apostropheStem);
|
|
536
536
|
}
|
|
537
537
|
}
|
|
538
|
+
const bareInfinitives = restoreInfinitive(normalized);
|
|
539
|
+
for (const inf of bareInfinitives) {
|
|
540
|
+
if (!seen.has(inf) && inf !== normalized) {
|
|
541
|
+
seen.add(inf);
|
|
542
|
+
candidatesWithWeight.push({ candidate: inf, baseLength: normalized.length });
|
|
543
|
+
}
|
|
544
|
+
}
|
|
538
545
|
let frontier = [normalized];
|
|
539
546
|
for (let depth = 0; depth < maxDepth; depth++) {
|
|
540
547
|
const nextFrontier = [];
|
|
@@ -584,6 +591,159 @@ import * as path from "path";
|
|
|
584
591
|
import * as os from "os";
|
|
585
592
|
import * as https from "https";
|
|
586
593
|
import * as tls from "tls";
|
|
594
|
+
var COMMON_MISSPELLINGS = {
|
|
595
|
+
// -şey ile biten ve ayrı yazılması zorunlu söz öbekleri
|
|
596
|
+
her\u015Fey: "her \u015Fey",
|
|
597
|
+
hersey: "her \u015Fey",
|
|
598
|
+
bir\u015Fey: "bir \u015Fey",
|
|
599
|
+
birsey: "bir \u015Fey",
|
|
600
|
+
hi\u00E7bir\u015Fey: "hi\xE7bir \u015Fey",
|
|
601
|
+
hicbirsey: "hi\xE7bir \u015Fey",
|
|
602
|
+
\u00E7ok\u015Fey: "\xE7ok \u015Fey",
|
|
603
|
+
coksey: "\xE7ok \u015Fey",
|
|
604
|
+
\u015Feyler: "\u015Feyler",
|
|
605
|
+
seyler: "\u015Feyler",
|
|
606
|
+
herhangibir\u015Fey: "herhangi bir \u015Fey",
|
|
607
|
+
herhangibirsey: "herhangi bir \u015Fey",
|
|
608
|
+
// Sıkça birleşik yazılan ama ayrı yazılması gereken sözler
|
|
609
|
+
herg\u00FCn: "her g\xFCn",
|
|
610
|
+
hergun: "her g\xFCn",
|
|
611
|
+
herzaman: "her zaman",
|
|
612
|
+
heran: "her an",
|
|
613
|
+
heryer: "her yer",
|
|
614
|
+
herbiri: "her biri",
|
|
615
|
+
pek\u00E7ok: "pek \xE7ok",
|
|
616
|
+
pekcok: "pek \xE7ok",
|
|
617
|
+
pekaz: "pek az",
|
|
618
|
+
yada: "ya da",
|
|
619
|
+
tabiki: "tabii ki",
|
|
620
|
+
tabiiki: "tabii ki",
|
|
621
|
+
sa\u011Fol: "sa\u011F ol",
|
|
622
|
+
sagol: "sa\u011F ol",
|
|
623
|
+
sa\u011Folun: "sa\u011F olun",
|
|
624
|
+
sagolun: "sa\u011F olun",
|
|
625
|
+
ho\u015F\u00E7akal: "ho\u015F\xE7a kal",
|
|
626
|
+
hoscakal: "ho\u015F\xE7a kal",
|
|
627
|
+
ho\u015Fgeldin: "ho\u015F geldin",
|
|
628
|
+
hosgeldin: "ho\u015F geldin",
|
|
629
|
+
ho\u015Fgeldiniz: "ho\u015F geldiniz",
|
|
630
|
+
hosgeldiniz: "ho\u015F geldiniz",
|
|
631
|
+
ho\u015Fbulduk: "ho\u015F bulduk",
|
|
632
|
+
hosbulduk: "ho\u015F bulduk",
|
|
633
|
+
yan\u0131s\u0131ra: "yan\u0131 s\u0131ra",
|
|
634
|
+
yanisira: "yan\u0131 s\u0131ra",
|
|
635
|
+
pe\u015Fis\u0131ra: "pe\u015Fi s\u0131ra",
|
|
636
|
+
pesisira: "pe\u015Fi s\u0131ra",
|
|
637
|
+
ard\u0131s\u0131ra: "ard\u0131 s\u0131ra",
|
|
638
|
+
ardisira: "ard\u0131 s\u0131ra",
|
|
639
|
+
artarda: "art arda",
|
|
640
|
+
y\u00FCzy\u00FCze: "y\xFCz y\xFCze",
|
|
641
|
+
yuzyuze: "y\xFCz y\xFCze",
|
|
642
|
+
elele: "el ele",
|
|
643
|
+
g\u00F6zg\u00F6ze: "g\xF6z g\xF6ze",
|
|
644
|
+
ba\u015Fba\u015Fa: "ba\u015F ba\u015Fa",
|
|
645
|
+
basbasa: "ba\u015F ba\u015Fa",
|
|
646
|
+
yanyana: "yan yana",
|
|
647
|
+
i\u00E7i\u00E7e: "i\xE7 i\xE7e",
|
|
648
|
+
icice: "i\xE7 i\xE7e",
|
|
649
|
+
\u00FCst\u00FCste: "\xFCst \xFCste",
|
|
650
|
+
ustuste: "\xFCst \xFCste",
|
|
651
|
+
altalta: "alt alta",
|
|
652
|
+
\u00F6ns\u00F6z: "\xF6n s\xF6z",
|
|
653
|
+
onsoz: "\xF6n s\xF6z",
|
|
654
|
+
\u00F6nyarg\u0131: "\xF6n yarg\u0131",
|
|
655
|
+
onyargi: "\xF6n yarg\u0131",
|
|
656
|
+
farketmek: "fark etmek",
|
|
657
|
+
farketti: "fark etti",
|
|
658
|
+
farkettim: "fark ettim",
|
|
659
|
+
farkeder: "fark eder",
|
|
660
|
+
farketmez: "fark etmez",
|
|
661
|
+
terketmek: "terk etmek",
|
|
662
|
+
terketti: "terk etti",
|
|
663
|
+
ay\u0131rdetmek: "ay\u0131rt etmek",
|
|
664
|
+
ay\u0131rtetmek: "ay\u0131rt etmek",
|
|
665
|
+
arzetmek: "arz etmek",
|
|
666
|
+
arzederim: "arz ederim",
|
|
667
|
+
varolmak: "var olmak",
|
|
668
|
+
yokolmak: "yok olmak",
|
|
669
|
+
haketmek: "hak etmek",
|
|
670
|
+
haketti: "hak etti",
|
|
671
|
+
hakkaten: "hakikaten",
|
|
672
|
+
hi\u00E7kimse: "hi\xE7 kimse",
|
|
673
|
+
hickimse: "hi\xE7 kimse",
|
|
674
|
+
// Ünlü düşmesi yapılmaması gereken yer bildiren sözler (TDK Kural 15)
|
|
675
|
+
burda: "burada",
|
|
676
|
+
burdan: "buradan",
|
|
677
|
+
\u015Furda: "\u015Furada",
|
|
678
|
+
surda: "\u015Furada",
|
|
679
|
+
\u015Furdan: "\u015Furadan",
|
|
680
|
+
surdan: "\u015Furadan",
|
|
681
|
+
orda: "orada",
|
|
682
|
+
ordan: "oradan",
|
|
683
|
+
i\u00E7erde: "i\xE7eride",
|
|
684
|
+
icerde: "i\xE7eride",
|
|
685
|
+
i\u00E7erden: "i\xE7eriden",
|
|
686
|
+
icerden: "i\xE7eriden",
|
|
687
|
+
d\u0131\u015Farda: "d\u0131\u015Far\u0131da",
|
|
688
|
+
disarda: "d\u0131\u015Far\u0131da",
|
|
689
|
+
d\u0131\u015Fardan: "d\u0131\u015Far\u0131dan",
|
|
690
|
+
disardan: "d\u0131\u015Far\u0131dan",
|
|
691
|
+
yukarda: "yukar\u0131da",
|
|
692
|
+
yukardan: "yukar\u0131dan",
|
|
693
|
+
// Sıkça yanlış yazılan sözcükler
|
|
694
|
+
herkez: "herkes",
|
|
695
|
+
yanl\u0131z: "yaln\u0131z",
|
|
696
|
+
yaln\u0131\u015F: "yanl\u0131\u015F",
|
|
697
|
+
orjinal: "orijinal",
|
|
698
|
+
labaratuar: "laboratuvar",
|
|
699
|
+
laboratuar: "laboratuvar",
|
|
700
|
+
\u015F\u00F6f\u00F6r: "\u015Fof\xF6r",
|
|
701
|
+
sofor: "\u015Fof\xF6r",
|
|
702
|
+
egzos: "egzoz",
|
|
703
|
+
eksoz: "egzoz",
|
|
704
|
+
ekzoz: "egzoz",
|
|
705
|
+
kiprik: "kirpik",
|
|
706
|
+
kirbit: "kibrit",
|
|
707
|
+
klavuz: "k\u0131lavuz",
|
|
708
|
+
k\u0131ravat: "kravat",
|
|
709
|
+
s\u00FCpriz: "s\xFCrpriz",
|
|
710
|
+
supriz: "s\xFCrpriz",
|
|
711
|
+
raslant\u0131: "rastlant\u0131",
|
|
712
|
+
hastahane: "hastane",
|
|
713
|
+
pastahane: "pastane",
|
|
714
|
+
postahane: "postane",
|
|
715
|
+
eczahane: "eczane",
|
|
716
|
+
meyva: "meyve",
|
|
717
|
+
sarm\u0131sak: "sar\u0131msak",
|
|
718
|
+
dinazor: "dinozor",
|
|
719
|
+
pantalon: "pantolon",
|
|
720
|
+
tesbih: "tespih",
|
|
721
|
+
ah\u00E7\u0131: "a\u015F\xE7\u0131",
|
|
722
|
+
matba: "matbaa",
|
|
723
|
+
idda: "iddia",
|
|
724
|
+
iddaa: "iddia",
|
|
725
|
+
muhattap: "muhatap",
|
|
726
|
+
tra\u015F: "t\u0131ra\u015F",
|
|
727
|
+
karn\u0131bahar: "karnabahar",
|
|
728
|
+
kareografi: "koreografi",
|
|
729
|
+
poa\u00E7a: "po\u011Fa\xE7a",
|
|
730
|
+
poha\u00E7a: "po\u011Fa\xE7a",
|
|
731
|
+
\u015Farz: "\u015Farj",
|
|
732
|
+
sarj: "\u015Farj",
|
|
733
|
+
makina: "makine",
|
|
734
|
+
m\u00FCsade: "m\xFCsaade",
|
|
735
|
+
entellekt\u00FCel: "entelekt\xFCel",
|
|
736
|
+
inisiyatif: "inisiyatif",
|
|
737
|
+
insiyatif: "inisiyatif",
|
|
738
|
+
sezeryan: "sezaryen",
|
|
739
|
+
dok\u00FCman: "dok\xFCman",
|
|
740
|
+
d\u00F6k\u00FCman: "dok\xFCman",
|
|
741
|
+
erozyon: "erozyon",
|
|
742
|
+
erizyon: "erozyon",
|
|
743
|
+
anane: "anneanne",
|
|
744
|
+
babaanne: "babaanne"
|
|
745
|
+
};
|
|
746
|
+
var SEY_EXCEPTIONS = /* @__PURE__ */ new Set(["d\xFC\u015Fey", "e\u015Fey", "konsey", "jersey", "\u015Fey"]);
|
|
587
747
|
var TDK = class {
|
|
588
748
|
static BASE_URL = "https://sozluk.gov.tr";
|
|
589
749
|
static AUDIO_API_HOST = "api.sozluk.gov.tr";
|
|
@@ -1147,25 +1307,45 @@ yDFx8r7i9vIJU5HS3moZLkYWAOilMaV9N56A9Bgb6dNcHkvg3NoaYA==
|
|
|
1147
1307
|
* Checks spelling and returns suggestions if wrong.
|
|
1148
1308
|
*/
|
|
1149
1309
|
static async checkSpelling(word) {
|
|
1310
|
+
if (!word || word.trim() === "") {
|
|
1311
|
+
return { isCorrect: false, word };
|
|
1312
|
+
}
|
|
1313
|
+
const cleanWord = word.trim().toLocaleLowerCase("tr-TR");
|
|
1150
1314
|
const results = await this.getWord(word);
|
|
1151
1315
|
if (results.length > 0) {
|
|
1152
1316
|
return { isCorrect: true, word };
|
|
1153
1317
|
}
|
|
1318
|
+
if (COMMON_MISSPELLINGS[cleanWord]) {
|
|
1319
|
+
return { isCorrect: false, word, suggestion: COMMON_MISSPELLINGS[cleanWord] };
|
|
1320
|
+
}
|
|
1321
|
+
const seyMatch = cleanWord.match(/^(.+?)(?:şey|sey)([ıiuaeüodekmnl]+)?$/);
|
|
1322
|
+
if (seyMatch && !SEY_EXCEPTIONS.has(cleanWord)) {
|
|
1323
|
+
let prefix = seyMatch[1];
|
|
1324
|
+
const suffix = seyMatch[2] || "";
|
|
1325
|
+
if (prefix === "hicbir")
|
|
1326
|
+
prefix = "hi\xE7bir";
|
|
1327
|
+
if (prefix === "cok")
|
|
1328
|
+
prefix = "\xE7ok";
|
|
1329
|
+
return {
|
|
1330
|
+
isCorrect: false,
|
|
1331
|
+
word,
|
|
1332
|
+
suggestion: `${prefix} \u015Fey${suffix}`
|
|
1333
|
+
};
|
|
1334
|
+
}
|
|
1154
1335
|
const daily = await this.getDailyContent();
|
|
1155
1336
|
if (daily) {
|
|
1156
|
-
const syydMatch = daily.syyd.find((s) => s.yanliskelime.toLocaleLowerCase("tr-TR") ===
|
|
1337
|
+
const syydMatch = daily.syyd.find((s) => s.yanliskelime.toLocaleLowerCase("tr-TR") === cleanWord);
|
|
1157
1338
|
if (syydMatch) {
|
|
1158
1339
|
return { isCorrect: false, word, suggestion: syydMatch.dogrukelime };
|
|
1159
1340
|
}
|
|
1160
|
-
const mixMatch = daily.karistirma.find((s) => s.yanlis.toLocaleLowerCase("tr-TR") ===
|
|
1341
|
+
const mixMatch = daily.karistirma.find((s) => s.yanlis.toLocaleLowerCase("tr-TR") === cleanWord);
|
|
1161
1342
|
if (mixMatch) {
|
|
1162
1343
|
return { isCorrect: false, word, suggestion: mixMatch.dogru };
|
|
1163
1344
|
}
|
|
1164
1345
|
}
|
|
1165
1346
|
const root = await this.findRoot(word);
|
|
1166
1347
|
if (root) {
|
|
1167
|
-
const
|
|
1168
|
-
const isInflected = root !== cleanWord2;
|
|
1348
|
+
const isInflected = root !== cleanWord;
|
|
1169
1349
|
return {
|
|
1170
1350
|
isCorrect: true,
|
|
1171
1351
|
word,
|
|
@@ -1176,24 +1356,32 @@ yDFx8r7i9vIJU5HS3moZLkYWAOilMaV9N56A9Bgb6dNcHkvg3NoaYA==
|
|
|
1176
1356
|
if (this.autocompleteCache.length === 0) {
|
|
1177
1357
|
this.autocompleteCache = await this.fetchAutocompleteData();
|
|
1178
1358
|
}
|
|
1179
|
-
const
|
|
1359
|
+
for (const candidate of this.autocompleteCache) {
|
|
1360
|
+
if (candidate.includes(" ")) {
|
|
1361
|
+
const candidateNoSpace = candidate.replace(/\s+/g, "").toLocaleLowerCase("tr-TR");
|
|
1362
|
+
if (candidateNoSpace === cleanWord) {
|
|
1363
|
+
return { isCorrect: false, word, suggestion: candidate };
|
|
1364
|
+
}
|
|
1365
|
+
}
|
|
1366
|
+
}
|
|
1180
1367
|
let best = null;
|
|
1181
1368
|
for (const candidate of this.autocompleteCache) {
|
|
1182
1369
|
if (candidate.includes(" ") || candidate !== candidate.toLocaleLowerCase("tr-TR"))
|
|
1183
1370
|
continue;
|
|
1184
1371
|
if (Math.abs(candidate.length - cleanWord.length) > 2)
|
|
1185
1372
|
continue;
|
|
1186
|
-
const
|
|
1187
|
-
if (
|
|
1373
|
+
const rawDist = this.damerauLevenshtein(cleanWord, candidate);
|
|
1374
|
+
if (rawDist === 0)
|
|
1188
1375
|
continue;
|
|
1189
1376
|
const firstMismatch = candidate[0] === cleanWord[0] ? 0 : 1;
|
|
1190
1377
|
const lengthMismatch = candidate.length === cleanWord.length ? 0 : 1;
|
|
1378
|
+
const distance = rawDist + (firstMismatch > 0 ? 1.2 : 0);
|
|
1191
1379
|
const better = !best || distance < best.distance || distance === best.distance && firstMismatch < best.firstMismatch || distance === best.distance && firstMismatch === best.firstMismatch && lengthMismatch < best.lengthMismatch;
|
|
1192
1380
|
if (better) {
|
|
1193
|
-
best = { candidate, distance, firstMismatch, lengthMismatch };
|
|
1381
|
+
best = { candidate, distance, rawDist, firstMismatch, lengthMismatch };
|
|
1194
1382
|
}
|
|
1195
1383
|
}
|
|
1196
|
-
if (best && best.
|
|
1384
|
+
if (best && best.rawDist <= 2 && (best.firstMismatch === 0 || best.rawDist <= 1)) {
|
|
1197
1385
|
return { isCorrect: false, word, suggestion: best.candidate };
|
|
1198
1386
|
}
|
|
1199
1387
|
return { isCorrect: false, word };
|
|
@@ -1946,6 +2134,73 @@ yDFx8r7i9vIJU5HS3moZLkYWAOilMaV9N56A9Bgb6dNcHkvg3NoaYA==
|
|
|
1946
2134
|
"me\u011Ferki",
|
|
1947
2135
|
"illaki"
|
|
1948
2136
|
]);
|
|
2137
|
+
const PHRASE_MISTAKES = [
|
|
2138
|
+
{
|
|
2139
|
+
regex: /\bhiç\s+bir\b/gi,
|
|
2140
|
+
suggestion: "hi\xE7bir",
|
|
2141
|
+
message: "'hi\xE7bir' belgisiz s\u0131fat\u0131 biti\u015Fik yaz\u0131lmal\u0131d\u0131r.",
|
|
2142
|
+
type: "spelling"
|
|
2143
|
+
},
|
|
2144
|
+
{
|
|
2145
|
+
regex: /\bbir\s+çok\b/gi,
|
|
2146
|
+
suggestion: "bir\xE7ok",
|
|
2147
|
+
message: "'bir\xE7ok' belgisiz s\u0131fat\u0131/zamiri biti\u015Fik yaz\u0131lmal\u0131d\u0131r.",
|
|
2148
|
+
type: "spelling"
|
|
2149
|
+
},
|
|
2150
|
+
{
|
|
2151
|
+
regex: /\bbir\s+kaç\b/gi,
|
|
2152
|
+
suggestion: "birka\xE7",
|
|
2153
|
+
message: "'birka\xE7' belgisiz s\u0131fat\u0131/zamiri biti\u015Fik yaz\u0131lmal\u0131d\u0131r.",
|
|
2154
|
+
type: "spelling"
|
|
2155
|
+
},
|
|
2156
|
+
{
|
|
2157
|
+
regex: /\bbir\s+az\b/gi,
|
|
2158
|
+
suggestion: "biraz",
|
|
2159
|
+
message: "'biraz' s\xF6zc\xFC\u011F\xFC biti\u015Fik yaz\u0131lmal\u0131d\u0131r.",
|
|
2160
|
+
type: "spelling"
|
|
2161
|
+
},
|
|
2162
|
+
{
|
|
2163
|
+
regex: /\bher\s+hangi\b/gi,
|
|
2164
|
+
suggestion: "herhangi",
|
|
2165
|
+
message: "'herhangi' s\xF6zc\xFC\u011F\xFC biti\u015Fik yaz\u0131lmal\u0131d\u0131r.",
|
|
2166
|
+
type: "spelling"
|
|
2167
|
+
},
|
|
2168
|
+
{
|
|
2169
|
+
regex: /\bgit\s+gide\b/gi,
|
|
2170
|
+
suggestion: "gitgide",
|
|
2171
|
+
message: "'gitgide' zarf\u0131 biti\u015Fik yaz\u0131lmal\u0131d\u0131r.",
|
|
2172
|
+
type: "spelling"
|
|
2173
|
+
},
|
|
2174
|
+
{
|
|
2175
|
+
regex: /\bbirden\s+bire\b/gi,
|
|
2176
|
+
suggestion: "birdenbire",
|
|
2177
|
+
message: "'birdenbire' zarf\u0131 biti\u015Fik yaz\u0131lmal\u0131d\u0131r.",
|
|
2178
|
+
type: "spelling"
|
|
2179
|
+
},
|
|
2180
|
+
{
|
|
2181
|
+
regex: /\brast\s+gele\b/gi,
|
|
2182
|
+
suggestion: "rastgele",
|
|
2183
|
+
message: "'rastgele' zarf\u0131 biti\u015Fik yaz\u0131lmal\u0131d\u0131r.",
|
|
2184
|
+
type: "spelling"
|
|
2185
|
+
}
|
|
2186
|
+
];
|
|
2187
|
+
const coveredRanges = [];
|
|
2188
|
+
for (const pm of PHRASE_MISTAKES) {
|
|
2189
|
+
let pmMatch;
|
|
2190
|
+
while ((pmMatch = pm.regex.exec(text)) !== null) {
|
|
2191
|
+
const start = pmMatch.index;
|
|
2192
|
+
const end = start + pmMatch[0].length;
|
|
2193
|
+
coveredRanges.push({ start, end });
|
|
2194
|
+
issues.push({
|
|
2195
|
+
type: pm.type,
|
|
2196
|
+
word: pmMatch[0],
|
|
2197
|
+
startIndex: start,
|
|
2198
|
+
endIndex: end,
|
|
2199
|
+
suggestion: pm.suggestion,
|
|
2200
|
+
message: pm.message
|
|
2201
|
+
});
|
|
2202
|
+
}
|
|
2203
|
+
}
|
|
1949
2204
|
const tokenRegex = /[\p{L}0-9'’]+/gu;
|
|
1950
2205
|
let match;
|
|
1951
2206
|
while ((match = tokenRegex.exec(text)) !== null) {
|
|
@@ -1955,6 +2210,8 @@ yDFx8r7i9vIJU5HS3moZLkYWAOilMaV9N56A9Bgb6dNcHkvg3NoaYA==
|
|
|
1955
2210
|
const lower = rawWord.toLocaleLowerCase("tr-TR");
|
|
1956
2211
|
if (/^\d+$/.test(lower))
|
|
1957
2212
|
continue;
|
|
2213
|
+
if (coveredRanges.some((r) => startIndex >= r.start && endIndex <= r.end))
|
|
2214
|
+
continue;
|
|
1958
2215
|
let flagged = false;
|
|
1959
2216
|
const questionMatch = lower.match(/^(.+?)(m[ıiuü](?:sin|sın|sun|sün|siniz|sınız|sunuz|sünüz|yiz|yız|yuz|yüz|m|k)?)$/);
|
|
1960
2217
|
if (questionMatch) {
|
|
@@ -1980,7 +2237,7 @@ yDFx8r7i9vIJU5HS3moZLkYWAOilMaV9N56A9Bgb6dNcHkvg3NoaYA==
|
|
|
1980
2237
|
if (!SOMBAHCEMI.has(lower)) {
|
|
1981
2238
|
if (!await this.isHeadword(lower)) {
|
|
1982
2239
|
const root = await this.findRoot(base);
|
|
1983
|
-
const isVerb =
|
|
2240
|
+
const isVerb = (base === "demek" || base === "kald\u0131" || base === "yeter" || base === "bilmem" || VERB_CONJUGATION_REGEX.test(base)) && (root ? root.endsWith("mek") || root.endsWith("mak") : true);
|
|
1984
2241
|
if (isVerb) {
|
|
1985
2242
|
issues.push({
|
|
1986
2243
|
type: "conjunction_ki",
|
|
@@ -2000,7 +2257,7 @@ yDFx8r7i9vIJU5HS3moZLkYWAOilMaV9N56A9Bgb6dNcHkvg3NoaYA==
|
|
|
2000
2257
|
const ending = lower.slice(-2);
|
|
2001
2258
|
if (!await this.isHeadword(lower)) {
|
|
2002
2259
|
const root = await this.findRoot(base);
|
|
2003
|
-
const isVerb =
|
|
2260
|
+
const isVerb = VERB_CONJUGATION_REGEX.test(base) && (root ? root.endsWith("mek") || root.endsWith("mak") : false);
|
|
2004
2261
|
if (isVerb) {
|
|
2005
2262
|
const correctEnding = ending.startsWith("t") ? ending === "te" ? "de" : "da" : ending;
|
|
2006
2263
|
issues.push({
|
|
@@ -2015,6 +2272,47 @@ yDFx8r7i9vIJU5HS3moZLkYWAOilMaV9N56A9Bgb6dNcHkvg3NoaYA==
|
|
|
2015
2272
|
}
|
|
2016
2273
|
}
|
|
2017
2274
|
}
|
|
2275
|
+
const seyMatch = lower.match(/^(.+?)(?:şey|sey)([ıiuaeüodekmnl]+)?$/);
|
|
2276
|
+
if (!flagged && seyMatch && !SEY_EXCEPTIONS.has(lower)) {
|
|
2277
|
+
let prefix = seyMatch[1];
|
|
2278
|
+
const suffix = seyMatch[2] || "";
|
|
2279
|
+
if (prefix === "hicbir")
|
|
2280
|
+
prefix = "hi\xE7bir";
|
|
2281
|
+
if (prefix === "cok")
|
|
2282
|
+
prefix = "\xE7ok";
|
|
2283
|
+
issues.push({
|
|
2284
|
+
type: "spelling",
|
|
2285
|
+
word: rawWord,
|
|
2286
|
+
startIndex,
|
|
2287
|
+
endIndex,
|
|
2288
|
+
suggestion: `${prefix} \u015Fey${suffix}`,
|
|
2289
|
+
message: "'\u015Fey' s\xF6zc\xFC\u011F\xFC kendinden \xF6nceki kelimeden ayr\u0131 yaz\u0131lmal\u0131d\u0131r."
|
|
2290
|
+
});
|
|
2291
|
+
flagged = true;
|
|
2292
|
+
}
|
|
2293
|
+
if (!flagged && lower === "yada") {
|
|
2294
|
+
issues.push({
|
|
2295
|
+
type: "spelling",
|
|
2296
|
+
word: rawWord,
|
|
2297
|
+
startIndex,
|
|
2298
|
+
endIndex,
|
|
2299
|
+
suggestion: "ya da",
|
|
2300
|
+
message: "'ya da' ba\u011Flac\u0131 her zaman ayr\u0131 yaz\u0131l\u0131r."
|
|
2301
|
+
});
|
|
2302
|
+
flagged = true;
|
|
2303
|
+
}
|
|
2304
|
+
if (!flagged && (lower === "burda" || lower === "\u015Furda" || lower === "surda" || lower === "orda" || lower === "i\xE7erde" || lower === "icerde" || lower === "d\u0131\u015Farda" || lower === "disarda" || lower === "yukarda")) {
|
|
2305
|
+
const correct = COMMON_MISSPELLINGS[lower] || lower;
|
|
2306
|
+
issues.push({
|
|
2307
|
+
type: "spelling",
|
|
2308
|
+
word: rawWord,
|
|
2309
|
+
startIndex,
|
|
2310
|
+
endIndex,
|
|
2311
|
+
suggestion: correct,
|
|
2312
|
+
message: `'${rawWord}' s\xF6zc\xFC\u011F\xFCnde \xFCnl\xFC d\xFC\u015Fmesi yap\u0131lmaz.`
|
|
2313
|
+
});
|
|
2314
|
+
flagged = true;
|
|
2315
|
+
}
|
|
2018
2316
|
if (!flagged) {
|
|
2019
2317
|
const check = await this.checkSpelling(rawWord);
|
|
2020
2318
|
if (!check.isCorrect) {
|
|
@@ -2024,11 +2322,12 @@ yDFx8r7i9vIJU5HS3moZLkYWAOilMaV9N56A9Bgb6dNcHkvg3NoaYA==
|
|
|
2024
2322
|
startIndex,
|
|
2025
2323
|
endIndex,
|
|
2026
2324
|
suggestion: check.suggestion,
|
|
2027
|
-
message: check.suggestion ? `'${rawWord}' yanl\u0131\u015F yaz\u0131lm\u0131\u015F olabilir
|
|
2325
|
+
message: check.suggestion ? `'${rawWord}' yanl\u0131\u015F yaz\u0131lm\u0131\u015F olabilir.` : `'${rawWord}' s\xF6zl\xFCkte bulunamad\u0131.`
|
|
2028
2326
|
});
|
|
2029
2327
|
}
|
|
2030
2328
|
}
|
|
2031
2329
|
}
|
|
2330
|
+
issues.sort((a, b) => a.startIndex - b.startIndex);
|
|
2032
2331
|
return {
|
|
2033
2332
|
text,
|
|
2034
2333
|
issues,
|