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

sile-typesetter / sile / 11124789710

01 Oct 2024 11:57AM UTC coverage: 29.567% (-31.4%) from 60.926%
11124789710

push

github

web-flow
Merge pull request #2105 from Omikhleia/refactor-collated-sort

0 of 10 new or added lines in 1 file covered. (0.0%)

5252 existing lines in 53 files now uncovered.

5048 of 17073 relevant lines covered (29.57%)

1856.13 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 hyphenation mark if the break
3
-- occurs at an apostrophe (kesme işareti). Some older guidance and some publishers
4
-- suggest dropping the apostrophe instead.
UNCOV
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
UNCOV
13
SILE.nodeMakers.tr = pl.class(SILE.nodeMakers.unicode)
×
UNCOV
14
SILE.nodeMakers.tr.wordTypes = { cm = true, qu = true }
×
15

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

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

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

717
-- Internationalization stuff
718

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

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

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

UNCOV
830
SU.formatNumber.tr = {
×
831
   string = function (num, _)
832
      return tr_nums(num, false)
×
833
   end,
834
   ["ordinal-string"] = function (num, _)
835
      return tr_nums(num, true)
×
836
   end,
837
}
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