• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

sile-typesetter / sile / 9441244789

10 Jun 2024 01:45AM UTC coverage: 49.048% (-11.6%) from 60.675%
9441244789

push

github

web-flow
Merge 8a4989eae into 519864108

8320 of 16963 relevant lines covered (49.05%)

1813.12 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/languages/tr.lua
1
-- Different years of TDK and various publisher style guides differ on this point.
2
-- Current official guidance suggests dropping the hypenation mark if the break
3
-- occurs at an apostrophe (kesme işareti). Some older guidance and some publishers
4
-- suggest dropping the apostrophe instead.
5
SILE.settings:declare({
×
6
   parameter = "languages.tr.replaceApostropheAtHyphenation",
7
   type = "boolean",
8
   default = false,
9
   help = "If enabled, substitute the apostophe for a hyphen at break points, otherwise keep the apostrophe and hide the hyphen.",
10
})
11

12
-- Quotes may be part of a word in Turkish
13
SILE.nodeMakers.tr = pl.class(SILE.nodeMakers.unicode)
×
14
SILE.nodeMakers.tr.wordTypes = { cm = true, qu = true }
×
15

16
SILE.hyphenator.languages["tr"] = {}
×
17

18
SILE.hyphenator.languages["tr"].hyphenateSegments = function (node, segments, j)
×
19
   local hyphenChar, replacement
20
   local maybeNextApostrophe = #segments > j and luautf8.match(segments[j + 1], "^['’]")
×
21
   if maybeNextApostrophe then
×
22
      segments[j + 1] = luautf8.gsub(segments[j + 1], "^['’]", "")
×
23
      if SILE.settings:get("languages.tr.replaceApostropheAtHyphenation") then
×
24
         hyphenChar = SILE.settings:get("font.hyphenchar")
×
25
      else
26
         hyphenChar = maybeNextApostrophe
×
27
         replacement = SILE.shaper:createNnodes(maybeNextApostrophe, node.options)
×
28
      end
29
   else
30
      hyphenChar = SILE.settings:get("font.hyphenchar")
×
31
   end
32
   local hyphen = SILE.shaper:createNnodes(hyphenChar, node.options)
×
33
   return SILE.types.node.discretionary({ replacement = replacement, prebreak = hyphen }), segments
×
34
end
35

36
SILE.hyphenator.languages["tr"].patterns = {
×
37
   "2a1",
38
   "2â1",
39
   "2e1",
40
   "2ı1",
41
   "2i1",
42
   "2î1",
43
   "2o1",
44
   "2ö1",
45
   "2u1",
46
   "2ü1",
47
   "2û1",
48
   -- allow hyphen either side of consonants
49
   "1b1",
50
   "1c1",
51
   "1ç1",
52
   "1d1",
53
   "1f1",
54
   "1g1",
55
   "1ğ1",
56
   "1h1",
57
   "1j1",
58
   "1k1",
59
   "1l1",
60
   "1m1",
61
   "1n1",
62
   "1p1",
63
   "1r1",
64
   "1s1",
65
   "1ş1",
66
   "1t1",
67
   "1v1",
68
   "1y1",
69
   "1z1",
70
   -- prevent a-cak/e-cek at end of word
71
   "2a2cak.",
72
   "2e2cek.",
73
   -- prohibit hyphen before pair of consonants
74
   -- many pairs generated here are impossible anyway
75
   "2bb",
76
   "2bc",
77
   "2bç",
78
   "2bd",
79
   "2bf",
80
   "2bg",
81
   "2bğ",
82
   "2bh",
83
   "2bj",
84
   "2bk",
85
   "2bl",
86
   "2bm",
87
   "2bn",
88
   "2bp",
89
   "2br",
90
   "2bs",
91
   "2bş",
92
   "2bt",
93
   "2bv",
94
   "2by",
95
   "2bz",
96
   "2cb",
97
   "2cc",
98
   "2cç",
99
   "2cd",
100
   "2cf",
101
   "2cg",
102
   "2cğ",
103
   "2ch",
104
   "2cj",
105
   "2ck",
106
   "2cl",
107
   "2cm",
108
   "2cn",
109
   "2cp",
110
   "2cr",
111
   "2cs",
112
   "2cş",
113
   "2ct",
114
   "2cv",
115
   "2cy",
116
   "2cz",
117
   "2çb",
118
   "2çc",
119
   "2çç",
120
   "2çd",
121
   "2çf",
122
   "2çg",
123
   "2çğ",
124
   "2çh",
125
   "2çj",
126
   "2çk",
127
   "2çl",
128
   "2çm",
129
   "2çn",
130
   "2çp",
131
   "2çr",
132
   "2çs",
133
   "2çş",
134
   "2çt",
135
   "2çv",
136
   "2çy",
137
   "2çz",
138
   "2db",
139
   "2dc",
140
   "2dç",
141
   "2dd",
142
   "2df",
143
   "2dg",
144
   "2dğ",
145
   "2dh",
146
   "2dj",
147
   "2dk",
148
   "2dl",
149
   "2dm",
150
   "2dn",
151
   "2dp",
152
   "2dr",
153
   "2ds",
154
   "2dş",
155
   "2dt",
156
   "2dv",
157
   "2dy",
158
   "2dz",
159
   "2fb",
160
   "2fc",
161
   "2fç",
162
   "2fd",
163
   "2ff",
164
   "2fg",
165
   "2fğ",
166
   "2fh",
167
   "2fj",
168
   "2fk",
169
   "2fl",
170
   "2fm",
171
   "2fn",
172
   "2fp",
173
   "2fr",
174
   "2fs",
175
   "2fş",
176
   "2ft",
177
   "2fv",
178
   "2fy",
179
   "2fz",
180
   "2gb",
181
   "2gc",
182
   "2gç",
183
   "2gd",
184
   "2gf",
185
   "2gg",
186
   "2gğ",
187
   "2gh",
188
   "2gj",
189
   "2gk",
190
   "2gl",
191
   "2gm",
192
   "2gn",
193
   "2gp",
194
   "2gr",
195
   "2gs",
196
   "2gş",
197
   "2gt",
198
   "2gv",
199
   "2gy",
200
   "2gz",
201
   "2ğb",
202
   "2ğc",
203
   "2ğç",
204
   "2ğd",
205
   "2ğf",
206
   "2ğg",
207
   "2ğğ",
208
   "2ğh",
209
   "2ğj",
210
   "2ğk",
211
   "2ğl",
212
   "2ğm",
213
   "2ğn",
214
   "2ğp",
215
   "2ğr",
216
   "2ğs",
217
   "2ğş",
218
   "2ğt",
219
   "2ğv",
220
   "2ğy",
221
   "2ğz",
222
   "2hb",
223
   "2hc",
224
   "2hç",
225
   "2hd",
226
   "2hf",
227
   "2hg",
228
   "2hğ",
229
   "2hh",
230
   "2hj",
231
   "2hk",
232
   "2hl",
233
   "2hm",
234
   "2hn",
235
   "2hp",
236
   "2hr",
237
   "2hs",
238
   "2hş",
239
   "2ht",
240
   "2hv",
241
   "2hy",
242
   "2hz",
243
   "2jb",
244
   "2jc",
245
   "2jç",
246
   "2jd",
247
   "2jf",
248
   "2jg",
249
   "2jğ",
250
   "2jh",
251
   "2jj",
252
   "2jk",
253
   "2jl",
254
   "2jm",
255
   "2jn",
256
   "2jp",
257
   "2jr",
258
   "2js",
259
   "2jş",
260
   "2jt",
261
   "2jv",
262
   "2jy",
263
   "2jz",
264
   "2kb",
265
   "2kc",
266
   "2kç",
267
   "2kd",
268
   "2kf",
269
   "2kg",
270
   "2kğ",
271
   "2kh",
272
   "2kj",
273
   "2kk",
274
   "2kl",
275
   "2km",
276
   "2kn",
277
   "2kp",
278
   "2kr",
279
   "2ks",
280
   "2kş",
281
   "2kt",
282
   "2kv",
283
   "2ky",
284
   "2kz",
285
   "2lb",
286
   "2lc",
287
   "2lç",
288
   "2ld",
289
   "2lf",
290
   "2lg",
291
   "2lğ",
292
   "2lh",
293
   "2lj",
294
   "2lk",
295
   "2ll",
296
   "2lm",
297
   "2ln",
298
   "2lp",
299
   "2lr",
300
   "2ls",
301
   "2lş",
302
   "2lt",
303
   "2lv",
304
   "2ly",
305
   "2lz",
306
   "2mb",
307
   "2mc",
308
   "2mç",
309
   "2md",
310
   "2mf",
311
   "2mg",
312
   "2mğ",
313
   "2mh",
314
   "2mj",
315
   "2mk",
316
   "2ml",
317
   "2mm",
318
   "2mn",
319
   "2mp",
320
   "2mr",
321
   "2ms",
322
   "2mş",
323
   "2mt",
324
   "2mv",
325
   "2my",
326
   "2mz",
327
   "2nb",
328
   "2nc",
329
   "2nç",
330
   "2nd",
331
   "2nf",
332
   "2ng",
333
   "2nğ",
334
   "2nh",
335
   "2nj",
336
   "2nk",
337
   "2nl",
338
   "2nm",
339
   "2nn",
340
   "2np",
341
   "2nr",
342
   "2ns",
343
   "2nş",
344
   "2nt",
345
   "2nv",
346
   "2ny",
347
   "2nz",
348
   "2pb",
349
   "2pc",
350
   "2pç",
351
   "2pd",
352
   "2pf",
353
   "2pg",
354
   "2pğ",
355
   "2ph",
356
   "2pj",
357
   "2pk",
358
   "2pl",
359
   "2pm",
360
   "2pn",
361
   "2pp",
362
   "2pr",
363
   "2ps",
364
   "2pş",
365
   "2pt",
366
   "2pv",
367
   "2py",
368
   "2pz",
369
   "2rb",
370
   "2rc",
371
   "2rç",
372
   "2rd",
373
   "2rf",
374
   "2rg",
375
   "2rğ",
376
   "2rh",
377
   "2rj",
378
   "2rk",
379
   "2rl",
380
   "2rm",
381
   "2rn",
382
   "2rp",
383
   "2rr",
384
   "2rs",
385
   "2rş",
386
   "2rt",
387
   "2rv",
388
   "2ry",
389
   "2rz",
390
   "2sb",
391
   "2sc",
392
   "2sç",
393
   "2sd",
394
   "2sf",
395
   "2sg",
396
   "2sğ",
397
   "2sh",
398
   "2sj",
399
   "2sk",
400
   "2sl",
401
   "2sm",
402
   "2sn",
403
   "2sp",
404
   "2sr",
405
   "2ss",
406
   "2sş",
407
   "2st",
408
   "2sv",
409
   "2sy",
410
   "2sz",
411
   "2şb",
412
   "2şc",
413
   "2şç",
414
   "2şd",
415
   "2şf",
416
   "2şg",
417
   "2şğ",
418
   "2şh",
419
   "2şj",
420
   "2şk",
421
   "2şl",
422
   "2şm",
423
   "2şn",
424
   "2şp",
425
   "2şr",
426
   "2şs",
427
   "2şş",
428
   "2şt",
429
   "2şv",
430
   "2şy",
431
   "2şz",
432
   "2tb",
433
   "2tc",
434
   "2tç",
435
   "2td",
436
   "2tf",
437
   "2tg",
438
   "2tğ",
439
   "2th",
440
   "2tj",
441
   "2tk",
442
   "2tl",
443
   "2tm",
444
   "2tn",
445
   "2tp",
446
   "2tr",
447
   "2ts",
448
   "2tş",
449
   "2tt",
450
   "2tv",
451
   "2ty",
452
   "2tz",
453
   "2vb",
454
   "2vc",
455
   "2vç",
456
   "2vd",
457
   "2vf",
458
   "2vg",
459
   "2vğ",
460
   "2vh",
461
   "2vj",
462
   "2vk",
463
   "2vl",
464
   "2vm",
465
   "2vn",
466
   "2vp",
467
   "2vr",
468
   "2vs",
469
   "2vş",
470
   "2vt",
471
   "2vv",
472
   "2vy",
473
   "2vz",
474
   "2yb",
475
   "2yc",
476
   "2yç",
477
   "2yd",
478
   "2yf",
479
   "2yg",
480
   "2yğ",
481
   "2yh",
482
   "2yj",
483
   "2yk",
484
   "2yl",
485
   "2ym",
486
   "2yn",
487
   "2yp",
488
   "2yr",
489
   "2ys",
490
   "2yş",
491
   "2yt",
492
   "2yv",
493
   "2yy",
494
   "2yz",
495
   "2zb",
496
   "2zc",
497
   "2zç",
498
   "2zd",
499
   "2zf",
500
   "2zg",
501
   "2zğ",
502
   "2zh",
503
   "2zj",
504
   "2zk",
505
   "2zl",
506
   "2zm",
507
   "2zn",
508
   "2zp",
509
   "2zr",
510
   "2zs",
511
   "2zş",
512
   "2zt",
513
   "2zv",
514
   "2zy",
515
   "2zz",
516
   -- allow hyphen between vowels, but not after second vowel of pair
517
   -- several phonetically impossible pairs here
518
   "a3a2",
519
   "a3â2",
520
   "a3e2",
521
   "a3ı2",
522
   "a3i2",
523
   "a3î2",
524
   "a3o2",
525
   "a3ö2",
526
   "a3u2",
527
   "a3ü2",
528
   "a3û2",
529
   "â3a2",
530
   "â3â2",
531
   "â3e2",
532
   "â3ı2",
533
   "â3i2",
534
   "â3î2",
535
   "â3o2",
536
   "â3ö2",
537
   "â3u2",
538
   "â3ü2",
539
   "â3û2",
540
   "e3a2",
541
   "e3â2",
542
   "e3e2",
543
   "e3ı2",
544
   "e3i2",
545
   "e3î2",
546
   "e3o2",
547
   "e3ö2",
548
   "e3u2",
549
   "e3ü2",
550
   "e3û2",
551
   "ı3a2",
552
   "ı3â2",
553
   "ı3e2",
554
   "ı3ı2",
555
   "ı3i2",
556
   "ı3î2",
557
   "ı3o2",
558
   "ı3ö2",
559
   "ı3u2",
560
   "ı3ü2",
561
   "ı3û2",
562
   "i3a2",
563
   "i3â2",
564
   "i3e2",
565
   "i3ı2",
566
   "i3i2",
567
   "i3î2",
568
   "i3o2",
569
   "i3ö2",
570
   "i3u2",
571
   "i3ü2",
572
   "i3û2",
573
   "î3a2",
574
   "î3â2",
575
   "î3e2",
576
   "î3ı2",
577
   "î3i2",
578
   "î3î2",
579
   "î3o2",
580
   "î3ö2",
581
   "î3u2",
582
   "î3ü2",
583
   "î3û2",
584
   "o3a2",
585
   "o3â2",
586
   "o3e2",
587
   "o3ı2",
588
   "o3i2",
589
   "o3î2",
590
   "o3o2",
591
   "o3ö2",
592
   "o3u2",
593
   "o3ü2",
594
   "o3û2",
595
   "ö3a2",
596
   "ö3â2",
597
   "ö3e2",
598
   "ö3ı2",
599
   "ö3i2",
600
   "ö3î2",
601
   "ö3o2",
602
   "ö3ö2",
603
   "ö3u2",
604
   "ö3ü2",
605
   "ö3û2",
606
   "u3a2",
607
   "u3â2",
608
   "u3e2",
609
   "u3ı2",
610
   "u3i2",
611
   "u3î2",
612
   "u3o2",
613
   "u3ö2",
614
   "u3u2",
615
   "u3ü2",
616
   "u3û2",
617
   "ü3a2",
618
   "ü3â2",
619
   "ü3e2",
620
   "ü3ı2",
621
   "ü3i2",
622
   "ü3î2",
623
   "ü3o2",
624
   "ü3ö2",
625
   "ü3u2",
626
   "ü3ü2",
627
   "ü3û2",
628
   "û3a2",
629
   "û3â2",
630
   "û3e2",
631
   "û3ı2",
632
   "û3i2",
633
   "û3î2",
634
   "û3o2",
635
   "û3ö2",
636
   "û3u2",
637
   "û3ü2",
638
   "û3û2",
639
   -- a couple of consonant-clusters
640
   "tu4r4k",
641
   "m1t4rak",
642
   -- See https://github.com/sile-typesetter/sile/issues/355
643
   -- Allow hyphenation to apply before apostrophes (before per pattern rules but
644
   -- will be substututed later, allowing after breaks minright), but work around
645
   -- minleft not being applied mid-word by excluding all possible single letter
646
   -- candidates before apostrophes.
647
   "1'2",
648
   "1’2",
649
   "4a1'",
650
   "4a1’",
651
   "4â1'",
652
   "4â1’",
653
   "4b1'",
654
   "4b1’",
655
   "4c1'",
656
   "4c1’",
657
   "4ç1'",
658
   "4ç1’",
659
   "4d1'",
660
   "4d1’",
661
   "4e1'",
662
   "4e1’",
663
   "4f1'",
664
   "4f1’",
665
   "4g1'",
666
   "4g1’",
667
   "4ğ1'",
668
   "4ğ1’",
669
   "4h1'",
670
   "4h1’",
671
   "4j1'",
672
   "4j1’",
673
   "4k1'",
674
   "4k1’",
675
   "4ı1'",
676
   "4ı1’",
677
   "4i1'",
678
   "4i1’",
679
   "4î1'",
680
   "4î1’",
681
   "4l1'",
682
   "4l1’",
683
   "4m1'",
684
   "4m1’",
685
   "4n1'",
686
   "4n1’",
687
   "4o1'",
688
   "4o1’",
689
   "4ö1'",
690
   "4ö1’",
691
   "4p1'",
692
   "4p1’",
693
   "4r1'",
694
   "4r1’",
695
   "4s1'",
696
   "4s1’",
697
   "4ş1'",
698
   "4ş1’",
699
   "4t1'",
700
   "4t1’",
701
   "4u1'",
702
   "4u1’",
703
   "4ü1'",
704
   "4ü1’",
705
   "4û1'",
706
   "4û1’",
707
   "4v1'",
708
   "4v1’",
709
   "4y1'",
710
   "4y1’",
711
   "4z1'",
712
   "4z1’",
713
}
714

715
-- Internationalisation stuff
716

717
-- local sum_tens = function (val, loc, digits)
718
--   local ten = string.sub(digits, loc+1, loc+1)
719
--   if ten:len() == 1 then val = val + tonumber(ten) * 10 end
720
--   return val
721
-- end
722

723
local sum_hundreds = function (val, loc, digits)
724
   local ten = string.sub(digits, loc + 1, loc + 1)
×
725
   local hundred = string.sub(digits, loc + 2, loc + 2)
×
726
   if ten:len() == 1 then
×
727
      val = val + tonumber(ten) * 10
×
728
   end
729
   if hundred:len() == 1 then
×
730
      val = val + tonumber(hundred) * 100
×
731
   end
732
   return val
×
733
end
734

735
local tr_nums = function (num, ordinal)
736
   local abs = math.abs(num)
×
737
   if abs >= 1e+36 then
×
738
      SU.error("Numbers past decillions not supported in Turkish")
×
739
   end
740
   ordinal = SU.boolean(ordinal, false)
×
741
   local minus = "eksi"
×
742
   local zero = "sıfır"
×
743
   local ones = { "bir", "iki", "üç", "dört", "beş", "altı", "yedi", "sekiz", "dokuz" }
×
744
   local tens = { "on", "yirmi", "otuz", "kırk", "eli", "altmış", "yetmiş", "seksen", "doksan" }
×
745
   local places = {
×
746
      "yüz",
747
      "bin",
748
      "milyon",
749
      "milyar",
750
      "trilyon",
751
      "katrilyon",
752
      "kentilyon",
753
      "sekstilyon",
754
      "septilyon",
755
      "oktilyon",
756
      "nonilyon",
757
      "desilyon",
758
   }
759
   local zeroordinal = "sıfırıncı"
×
760
   local onesordinals =
761
      { "birinci", "ikinci", "üçüncü", "dördüncü", "beşinci", "altıncı", "yedinci", "sekizinci", "dokuzuncu" }
×
762
   local tensordinals = {
×
763
      "onuncu",
764
      "yirmiyinci",
765
      "otuzuncu",
766
      "kırkıncı",
767
      "eliyinci",
768
      "altmışıncı",
769
      "yetmişinci",
770
      "sekseninci",
771
      "Doksanıncı",
772
   }
773
   local placesordinals = {
×
774
      "yüzüncü",
775
      "bininci",
776
      "milyonuncu",
777
      "milyarıncı",
778
      "trilyonuncu",
779
      "katrilyonuncu",
780
      "kentilyonuncu",
781
      "sekstilyonuncu",
782
      "septilyonuncu",
783
      "oktilyonuncu",
784
      "nonilyonuncu",
785
      "desilyonuncu",
786
   }
787
   local digits = string.reverse(string.format("%.f", abs))
×
788
   local words = {}
×
789
   for i = 1, #digits do
×
790
      local val, place, mod = tonumber(string.sub(digits, i, i)), math.floor(i / 3), i % 3
×
791
      if #digits == 1 and val == 0 then
×
792
         words[#words + 1] = ordinal and zeroordinal or zero
×
793
      elseif val >= 1 or i > 1 then
×
794
         if i == 1 then
×
795
            words[#words + 1] = ordinal and onesordinals[val] or ones[val]
×
796
            ordinal = false
×
797
         elseif mod == 2 then
×
798
            if val >= 1 then
×
799
               words[#words + 1] = ordinal and tensordinals[val] or tens[val]
×
800
               ordinal = false
×
801
            end
802
         elseif mod == 1 then
×
803
            if sum_hundreds(val, i, digits) >= 1 then
×
804
               words[#words + 1] = ordinal and placesordinals[place + 1] or places[place + 1]
×
805
               ordinal = false
×
806
               if val > 0 and (i >= 7 or sum_hundreds(val, i, digits) >= 2) then
×
807
                  words[#words + 1] = ones[val]
×
808
               end
809
            end
810
         elseif mod == 0 then
×
811
            if val > 0 then
×
812
               words[#words + 1] = ordinal and placesordinals[1] or places[1]
×
813
               ordinal = false
×
814
            end
815
            if val >= 2 then
×
816
               words[#words + 1] = ones[val]
×
817
            end
818
         end
819
      end
820
   end
821
   if abs > num then
×
822
      words[#words + 1] = minus
×
823
   end
824
   SU.flip_in_place(words)
×
825
   return table.concat(words, " ")
×
826
end
827

828
SU.formatNumber.tr = {
×
829
   string = function (num, _)
830
      return tr_nums(num, false)
×
831
   end,
832
   ["ordinal-string"] = function (num, _)
833
      return tr_nums(num, true)
×
834
   end,
835
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc