1if not modules then modules = { } end modules ['scrp-cjk'] = {
2 version = 1.001,
3 comment = "companion to scrp-ini.mkiv",
4 author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
5 copyright = "PRAGMA ADE / ConTeXt Development Team",
6 license = "see context related readme files"
7}
8
9
10
11
12
13
14
15
16
17
18
19
20local nuts = nodes.nuts
21
22local copy_node = nuts.copy
23local remove_node = nuts.remove
24local nextglyph = nuts.traversers.glyph
25
26local getnext = nuts.getnext
27local getprev = nuts.getprev
28local getfont = nuts.getfont
29local getchar = nuts.getchar
30local getid = nuts.getid
31local getsubtype = nuts.getsubtype
32local getwidth = nuts.getwidth
33
34local setchar = nuts.setchar
35
36local nodepool = nuts.pool
37local new_glue = nodepool.glue
38local new_kern = nodepool.kern
39local new_penalty = nodepool.penalty
40
41local nodecodes = nodes.nodecodes
42local gluecodes = nodes.gluecodes
43
44local glyph_code = nodecodes.glyph
45local glue_code = nodecodes.glue
46
47local userskip_code = gluecodes.userskip
48local spaceskip_code = gluecodes.spaceskip
49local xspaceskip_code = gluecodes.xspaceskip
50
51local hash = characters.scripthash
52
53local getscriptstatus = scripts.getstatus
54local getscriptdata = scripts.getdata
55local scriptcolors = scripts.colors
56
57local fonthashes = fonts.hashes
58local quaddata = fonthashes.quads
59local spacedata = fonthashes.spaces
60
61local decomposed = characters.hangul.decomposed
62
63local trace_details = false trackers.register("scripts.details", function(v) trace_details = v end)
64
65local report_details = logs.reporter("scripts","detail")
66
67
68
69
70
71local insertnodeafter = scripts.helpers.insertnodeafter
72local insertnodebefore = scripts.helpers.insertnodebefore
73
74local inter_char_shrink = 0
75local inter_char_stretch = 0
76local inter_char_half_shrink = 0
77local inter_char_half_stretch = 0
78local inter_char_quarter_shrink = 0
79local inter_char_quarter_stretch = 0
80
81local full_char_width = 0
82local half_char_width = 0
83local quarter_char_width = 0
84
85local inter_char_hangul_penalty = 0
86
87local function set_parameters(font,data)
88
89 local quad = quaddata[font]
90 full_char_width = quad
91 half_char_width = quad/2
92 quarter_char_width = quad/4
93 inter_char_shrink = data.inter_char_shrink_factor * quad
94 inter_char_stretch = data.inter_char_stretch_factor * quad
95 inter_char_half_shrink = data.inter_char_half_shrink_factor * quad
96 inter_char_half_stretch = data.inter_char_half_stretch_factor * quad
97 inter_char_quarter_shrink = data.inter_char_quarter_shrink_factor * quad
98 inter_char_quarter_stretch = data.inter_char_quarter_stretch_factor * quad
99 inter_char_hangul_penalty = data.inter_char_hangul_penalty
100end
101
102
103
104
105local function trace_detail(current,what)
106 local prev = getprev(current)
107 local c_id = getid(current)
108 local p_id = prev and getid(prev)
109 if c_id == glyph_code then
110 local c_ch = getchar(current)
111 if p_id == glyph_code then
112 local p_ch = p_id and getchar(prev)
113 report_details("[%C %a] [%s] [%C %a]",p_ch,hash[p_ch],what,c_ch,hash[c_ch])
114 else
115 report_details("[%s] [%C %a]",what,c_ch,hash[c_ch])
116 end
117 else
118 if p_id == glyph_code then
119 local p_ch = p_id and getchar(prev)
120 report_details("[%C %a] [%s]",p_ch,hash[p_ch],what)
121 else
122 report_details("[%s]",what)
123 end
124 end
125end
126
127local function trace_detail_between(p,n,what)
128 local p_ch = getchar(p)
129 local n_ch = getchar(n)
130 report_details("[%C %a] [%s] [%C %a]",p_ch,hash[p_ch],what,n_ch,hash[n_ch])
131end
132
133local function nobreak(head,current)
134 if trace_details then
135 trace_detail(current,"break")
136 end
137 insertnodebefore(head,current,new_penalty(10000))
138end
139
140local function stretch_break(head,current)
141 if trace_details then
142 trace_detail(current,"stretch break")
143 end
144 insertnodebefore(head,current,new_glue(0,inter_char_stretch,0))
145end
146
147local function shrink_break(head,current)
148 if trace_details then
149 trace_detail(current,"shrink break")
150 end
151 insertnodebefore(head,current,new_glue(0,0,inter_char_half_shrink))
152end
153
154local function nobreak_stretch(head,current)
155 if trace_details then
156 trace_detail(current,"no break stretch")
157 end
158 insertnodebefore(head,current,new_penalty(10000))
159 insertnodebefore(head,current,new_glue(0,inter_char_stretch,0))
160end
161
162local function korean_break(head,current)
163 if trace_details then
164 trace_detail(current,"korean break")
165 end
166 insertnodebefore(head,current,new_penalty(inter_char_hangul_penalty))
167end
168
169local function nobreak_shrink(head,current)
170 if trace_details then
171 trace_detail(current,"nobreak shrink")
172 end
173 insertnodebefore(head,current,new_penalty(10000))
174 insertnodebefore(head,current,new_glue(0,0,inter_char_half_shrink))
175end
176
177local function nobreak_autoshrink(head,current)
178 if trace_details then
179 trace_detail(current,"nobreak autoshrink")
180 end
181 insertnodebefore(head,current,new_penalty(10000))
182 insertnodebefore(head,current,new_glue(0,0,inter_char_half_shrink))
183end
184
185local function nobreak_stretch_nobreak_shrink(head,current)
186 if trace_details then
187 trace_detail(current,"nobreak stretch nobreak shrink")
188 end
189 insertnodebefore(head,current,new_penalty(10000))
190 insertnodebefore(head,current,new_glue(0,inter_char_stretch,0))
191 insertnodebefore(head,current,new_penalty(10000))
192 insertnodebefore(head,current,new_glue(0,0,inter_char_half_shrink))
193end
194
195local function nobreak_stretch_nobreak_autoshrink(head,current)
196 if trace_details then
197 trace_detail(current,"nobreak stretch nobreak autoshrink")
198 end
199 insertnodebefore(head,current,new_penalty(10000))
200 insertnodebefore(head,current,new_glue(0,inter_char_stretch,0))
201 insertnodebefore(head,current,new_penalty(10000))
202 insertnodebefore(head,current,new_glue(0,0,inter_char_half_shrink))
203end
204
205local function nobreak_shrink_nobreak_stretch(head,current)
206 if trace_details then
207 trace_detail(current,"nobreak shrink nobreak stretch")
208 end
209 insertnodebefore(head,current,new_penalty(10000))
210 insertnodebefore(head,current,new_glue(0,0,inter_char_half_shrink))
211 insertnodebefore(head,current,new_penalty(10000))
212 insertnodebefore(head,current,new_glue(0,inter_char_stretch,0))
213end
214
215local function nobreak_autoshrink_nobreak_stretch(head,current)
216 if trace_details then
217 trace_detail(current,"nobreak autoshrink nobreak stretch")
218 end
219 insertnodebefore(head,current,new_penalty(10000))
220 insertnodebefore(head,current,new_glue(0,0,inter_char_half_shrink))
221 insertnodebefore(head,current,new_penalty(10000))
222 insertnodebefore(head,current,new_glue(0,inter_char_stretch,0))
223end
224
225local function nobreak_shrink_break_stretch(head,current)
226 if trace_details then
227 trace_detail(current,"nobreak shrink break stretch")
228 end
229 insertnodebefore(head,current,new_penalty(10000))
230 insertnodebefore(head,current,new_glue(0,0,inter_char_half_shrink))
231 insertnodebefore(head,current,new_glue(0,inter_char_stretch,0))
232end
233
234local function nobreak_autoshrink_break_stretch(head,current)
235 if trace_details then
236 trace_detail(current,"nobreak autoshrink break stretch")
237 end
238 insertnodebefore(head,current,new_penalty(10000))
239 insertnodebefore(head,current,new_glue(0,0,inter_char_half_shrink))
240 insertnodebefore(head,current,new_glue(0,inter_char_stretch,0))
241end
242
243local function nobreak_shrink_break_stretch_nobreak_shrink(head,current)
244 if trace_details then
245 trace_detail(current,"nobreak shrink break stretch nobreak shrink")
246 end
247 insertnodebefore(head,current,new_penalty(10000))
248 insertnodebefore(head,current,new_glue(0,0,inter_char_half_shrink))
249 insertnodebefore(head,current,new_glue(0,inter_char_stretch,0))
250 insertnodebefore(head,current,new_penalty(10000))
251 insertnodebefore(head,current,new_glue(0,inter_char_stretch,0))
252end
253
254local function japanese_between_full_close_open(head,current)
255 if trace_details then
256 trace_detail(current,"japanese between full close open")
257 end
258 insertnodebefore(head,current,new_kern(-half_char_width))
259 insertnodebefore(head,current,new_glue(half_char_width,0,inter_char_half_shrink))
260 insertnodebefore(head,current,new_kern(-half_char_width))
261end
262
263local function japanese_between_full_close_full_close(head,current)
264 if trace_details then
265 trace_detail(current,"japanese between full close full close")
266 end
267 insertnodebefore(head,current,new_kern(-half_char_width))
268
269end
270
271local function japanese_before_full_width_punct(head,current)
272 if trace_details then
273 trace_detail(current,"japanese before full width punct")
274 end
275 insertnodebefore(head,current,new_penalty(10000))
276 insertnodebefore(head,current,new_glue(quarter_char_width,0,inter_char_quarter_shrink))
277 insertnodebefore(head,current,new_kern(-quarter_char_width))
278end
279
280local function japanese_after_full_width_punct(head,current)
281 if trace_details then
282 trace_detail(current,"japanese after full width punct")
283 end
284 insertnodebefore(head,current,new_kern(-quarter_char_width))
285 insertnodebefore(head,current,new_glue(quarter_char_width,0,inter_char_quarter_shrink))
286end
287
288local function nobreak_autoshrink_break_stretch_nobreak_autoshrink(head,current)
289 if trace_details then
290 trace_detail(current,"nobreak autoshrink break stretch nobreak autoshrink")
291 end
292 insertnodebefore(head,current,new_penalty(10000))
293 insertnodebefore(head,current,new_glue(0,0,inter_char_half_shrink))
294 insertnodebefore(head,current,new_glue(0,inter_char_stretch,0))
295 insertnodebefore(head,current,new_penalty(10000))
296 insertnodebefore(head,current,new_glue(0,0,inter_char_half_shrink))
297end
298
299local function nobreak_autoshrink_break_stretch_nobreak_shrink(head,current)
300 if trace_details then
301 trace_detail(current,"nobreak autoshrink break stretch nobreak shrink")
302 end
303 insertnodebefore(head,current,new_penalty(10000))
304 insertnodebefore(head,current,new_glue(0,0,inter_char_half_shrink))
305 insertnodebefore(head,current,new_glue(0,inter_char_stretch,0))
306 insertnodebefore(head,current,new_penalty(10000))
307 insertnodebefore(head,current,new_glue(0,0,inter_char_half_shrink))
308end
309
310local function nobreak_shrink_break_stretch_nobreak_autoshrink(head,current)
311 if trace_details then
312 trace_detail(current,"nobreak shrink break stretch nobreak autoshrink")
313 end
314 insertnodebefore(head,current,new_penalty(10000))
315 insertnodebefore(head,current,new_glue(0,0,inter_char_half_shrink))
316 insertnodebefore(head,current,new_glue(0,inter_char_stretch,0))
317 insertnodebefore(head,current,new_penalty(10000))
318 insertnodebefore(head,current,new_glue(0,inter_char_stretch,0))
319end
320
321local function nobreak_stretch_break_shrink(head,current)
322 if trace_details then
323 trace_detail(current,"nobreak stretch break shrink")
324 end
325 insertnodebefore(head,current,new_penalty(10000))
326 insertnodebefore(head,current,new_glue(0,inter_char_stretch,0))
327 insertnodebefore(head,current,new_glue(0,0,inter_char_half_shrink))
328end
329
330local function nobreak_stretch_break_autoshrink(head,current)
331 if trace_details then
332 trace_detail(current,"nobreak stretch break autoshrink")
333 end
334 insertnodebefore(head,current,new_penalty(10000))
335 insertnodebefore(head,current,new_glue(0,inter_char_stretch,0))
336 insertnodebefore(head,current,new_glue(0,0,inter_char_half_shrink))
337end
338
339
340
341local korean_0 = {
342}
343
344local korean_1 = {
345 jamo_initial = korean_break,
346 korean = korean_break,
347 chinese = korean_break,
348 hiragana = korean_break,
349 katakana = korean_break,
350 half_width_open = stretch_break,
351 half_width_close = nobreak,
352 full_width_open = stretch_break,
353 full_width_close = nobreak,
354 full_width_punct = nobreak,
355
356 non_starter = korean_break,
357 other = korean_break,
358}
359
360local korean_2 = {
361 jamo_initial = stretch_break,
362 korean = stretch_break,
363 chinese = stretch_break,
364 hiragana = stretch_break,
365 katakana = stretch_break,
366 half_width_open = stretch_break,
367 half_width_close = nobreak,
368 full_width_open = stretch_break,
369 full_width_close = nobreak,
370 full_width_punct = nobreak,
371
372 non_starter = stretch_break,
373 other = stretch_break,
374}
375
376local korean_3 = {
377 jamo_initial = stretch_break,
378 korean = stretch_break,
379 chinese = stretch_break,
380 hiragana = stretch_break,
381 katakana = stretch_break,
382 half_width_open = stretch_break,
383 half_width_close = nobreak,
384 full_width_open = stretch_break,
385 full_width_close = nobreak,
386 full_width_punct = nobreak,
387
388 non_starter = nobreak,
389 other = nobreak,
390}
391
392local korean_4 = {
393 jamo_initial = nobreak,
394 korean = nobreak,
395 chinese = nobreak,
396 hiragana = nobreak,
397 katakana = nobreak,
398 half_width_open = nobreak,
399 half_width_close = nobreak,
400 full_width_open = nobreak,
401 full_width_close = nobreak,
402 full_width_punct = nobreak,
403 hyphen = nobreak,
404 non_starter = nobreak,
405 other = nobreak,
406}
407
408local korean_5 = {
409 jamo_initial = stretch_break,
410 korean = stretch_break,
411 chinese = stretch_break,
412 hiragana = stretch_break,
413 katakana = stretch_break,
414 half_width_open = stretch_break,
415 half_width_close = nobreak_stretch,
416 full_width_open = stretch_break,
417 full_width_close = nobreak_stretch,
418 full_width_punct = nobreak_stretch,
419 hyphen = nobreak_stretch,
420 non_starter = nobreak_stretch,
421 other = stretch_break,
422}
423
424local injectors = {
425 jamo_final = korean_1,
426 korean = korean_1,
427 chinese = korean_1,
428 hiragana = korean_1,
429 katakana = korean_1,
430 hyphen = korean_2,
431 start = korean_0,
432 other = korean_2,
433 non_starter = korean_3,
434 full_width_open = korean_4,
435 half_width_open = korean_4,
436 full_width_close = korean_5,
437 full_width_punct = korean_5,
438 half_width_close = korean_5,
439}
440
441scriptcolors.korean = "trace:0"
442scriptcolors.chinese = "trace:0"
443scriptcolors.katakana = "trace:0"
444scriptcolors.hiragana = "trace:0"
445scriptcolors.full_width_open = "trace:1"
446scriptcolors.full_width_close = "trace:2"
447scriptcolors.half_width_open = "trace:3"
448scriptcolors.half_width_close = "trace:4"
449scriptcolors.full_width_punct = "trace:5"
450
451scriptcolors.non_starter = "trace:6"
452scriptcolors.jamo_initial = "trace:7"
453scriptcolors.jamo_medial = "trace:8"
454scriptcolors.jamo_final = "trace:9"
455
456local function process(head,first,last)
457 if first ~= last then
458 local lastfont = nil
459 local previous = "start"
460 local last = nil
461 while true do
462 local upcoming = getnext(first)
463 local id = getid(first)
464 if id == glyph_code then
465 local current = getscriptstatus(first)
466 local action = injectors[previous]
467 if action then
468 action = action[current]
469 if action then
470 local font = getfont(first)
471 if font ~= lastfont then
472 lastfont = font
473 set_parameters(font,getscriptdata(first))
474 end
475 action(head,first)
476 end
477 end
478 previous = current
479 else
480 local p = getprev(first)
481 local n = upcoming
482 if p and n then
483 local pid = getid(p)
484 local nid = getid(n)
485 if pid == glyph_code and nid == glyph_code then
486 local pcjk = getscriptstatus(p)
487 local ncjk = getscriptstatus(n)
488 if not pcjk or not ncjk
489 or pcjk == "korean" or ncjk == "korean"
490 or pcjk == "other" or ncjk == "other"
491 or pcjk == "jamo_final" or ncjk == "jamo_initial" then
492 previous = "start"
493 else
494 remove_node(head,first,true)
495 previous = pcjk
496
497
498 end
499 else
500 previous = "start"
501 end
502 else
503 previous = "start"
504 end
505 end
506 if upcoming == last then
507 break
508 else
509 first = upcoming
510 end
511 end
512 end
513end
514
515scripts.installmethod {
516 name = "hangul",
517 injector = process,
518 datasets = {
519 default = {
520 inter_char_shrink_factor = 0.50,
521 inter_char_stretch_factor = 0.50,
522 inter_char_half_shrink_factor = 0.50,
523 inter_char_half_stretch_factor = 0.50,
524 inter_char_quarter_shrink_factor = 0.50,
525 inter_char_quarter_stretch_factor = 0.50,
526 inter_char_hangul_penalty = 50,
527 },
528 tight = {
529 inter_char_shrink_factor = 0.10,
530 inter_char_stretch_factor = 0.10,
531 inter_char_half_shrink_factor = 0.10,
532 inter_char_half_stretch_factor = 0.10,
533 inter_char_quarter_shrink_factor = 0.10,
534 inter_char_quarter_stretch_factor = 0.10,
535 inter_char_hangul_penalty = 50,
536 },
537 },
538}
539
540function scripts.decomposehangul(head)
541 local done = false
542 for current, char in nextglyph, head do
543 local lead_consonant, medial_vowel, tail_consonant = decomposed(char)
544 if lead_consonant then
545 setchar(current,lead_consonant)
546 local m = copy_node(current)
547 setchar(m,medial_vowel)
548 head, current = insertnodeafter(head,current,m)
549 if tail_consonant then
550 local t = copy_node(current)
551 setchar(t,tail_consonant)
552 head, current = insertnodeafter(head,current,t)
553 end
554 done = true
555 end
556 end
557 return head, done
558end
559
560
561
562local otffeatures = fonts.constructors.features.otf
563local registerotffeature = otffeatures.register
564
565registerotffeature {
566 name = "decomposehangul",
567 description = "decompose hangul",
568 processors = {
569 position = 1,
570 node = scripts.decomposehangul,
571 }
572}
573
574
575
576local chinese_0 = {
577}
578
579local chinese_1 = {
580 jamo_initial = korean_break,
581 korean = korean_break,
582 chinese = stretch_break,
583 hiragana = stretch_break,
584 katakana = stretch_break,
585 half_width_open = nobreak_stretch_break_autoshrink,
586 half_width_close = nobreak_stretch,
587 full_width_open = nobreak_stretch_break_shrink,
588 full_width_close = nobreak_stretch,
589 full_width_punct = nobreak_stretch,
590
591 non_starter = nobreak_stretch,
592 other = stretch_break,
593}
594
595local chinese_2 = {
596 jamo_initial = korean_break,
597 korean = stretch_break,
598 chinese = stretch_break,
599 hiragana = stretch_break,
600 katakana = stretch_break,
601 half_width_open = nobreak_stretch_break_autoshrink,
602 half_width_close = nobreak_stretch,
603 full_width_open = nobreak_stretch_break_shrink,
604 full_width_close = nobreak_stretch,
605 full_width_punct = nobreak_stretch,
606 hyphen = nobreak_stretch,
607 non_starter = nobreak_stretch,
608 other = stretch_break,
609}
610
611local chinese_3 = {
612 jamo_initial = korean_break,
613 korean = stretch_break,
614 chinese = stretch_break,
615 hiragana = stretch_break,
616 katakana = stretch_break,
617 half_width_open = nobreak_stretch_break_autoshrink,
618 half_width_close = nobreak_stretch,
619 full_width_open = nobreak_stretch_break_shrink,
620 full_width_close = nobreak_stretch,
621 full_width_punct = nobreak_stretch,
622
623 non_starter = nobreak_stretch,
624 other = stretch_break,
625}
626
627local chinese_4 = {
628
629
630
631
632
633 half_width_open = nobreak_autoshrink,
634 half_width_close = nil,
635 full_width_open = nobreak_shrink,
636 full_width_close = nobreak,
637 full_width_punct = nobreak,
638
639 non_starter = nobreak,
640
641}
642
643local chinese_5 = {
644 jamo_initial = stretch_break,
645 korean = stretch_break,
646 chinese = stretch_break,
647 hiragana = stretch_break,
648 katakana = stretch_break,
649 half_width_open = nobreak_stretch_break_autoshrink,
650 half_width_close = nobreak_stretch,
651 full_width_open = nobreak_stretch_break_shrink,
652 full_width_close = nobreak_stretch,
653 full_width_punct = nobreak_stretch,
654
655 non_starter = nobreak_stretch,
656 other = stretch_break,
657}
658
659local chinese_6 = {
660 jamo_initial = nobreak_stretch,
661 korean = nobreak_stretch,
662 chinese = nobreak_stretch,
663 hiragana = nobreak_stretch,
664 katakana = nobreak_stretch,
665 half_width_open = nobreak_stretch_break_autoshrink,
666 half_width_close = nobreak_stretch,
667 full_width_open = nobreak_stretch_break_shrink,
668 full_width_close = nobreak_stretch,
669 full_width_punct = nobreak_stretch,
670 hyphen = nobreak_stretch,
671 non_starter = nobreak_stretch,
672 other = nobreak_stretch,
673}
674
675local chinese_7 = {
676 jami_initial = nobreak_shrink_break_stretch,
677 korean = nobreak_shrink_break_stretch,
678 chinese = stretch_break,
679 hiragana = stretch_break,
680 katakana = stretch_break,
681 half_width_open = nobreak_shrink_break_stretch_nobreak_autoshrink,
682 half_width_close = nobreak_shrink_nobreak_stretch,
683 full_width_open = nobreak_shrink_break_stretch_nobreak_shrink,
684 full_width_close = nobreak_shrink_nobreak_stretch,
685 full_width_punct = nobreak_shrink_nobreak_stretch,
686 hyphen = nobreak_shrink_break_stretch,
687 non_starter = nobreak_shrink_break_stretch,
688 other = nobreak_shrink_break_stretch,
689}
690
691local chinese_8 = {
692 jami_initial = nobreak_shrink_break_stretch,
693 korean = nobreak_autoshrink_break_stretch,
694 chinese = stretch_break,
695 hiragana = stretch_break,
696 katakana = stretch_break,
697 half_width_open = nobreak_autoshrink_break_stretch_nobreak_autoshrink,
698 half_width_close = nobreak_autoshrink_nobreak_stretch,
699 full_width_open = nobreak_autoshrink_break_stretch_nobreak_shrink,
700 full_width_close = nobreak_autoshrink_nobreak_stretch,
701 full_width_punct = nobreak_autoshrink_nobreak_stretch,
702 hyphen = nobreak_autoshrink_break_stretch,
703 non_starter = nobreak_autoshrink_break_stretch,
704 other = nobreak_autoshrink_break_stretch,
705}
706
707local injectors = {
708 jamo_final = chinese_1,
709 korean = chinese_1,
710 chinese = chinese_2,
711 hiragana = chinese_2,
712 katakana = chinese_2,
713 hyphen = chinese_3,
714 start = chinese_4,
715 other = chinese_5,
716 non_starter = chinese_5,
717 full_width_open = chinese_6,
718 half_width_open = chinese_6,
719 full_width_close = chinese_7,
720 full_width_punct = chinese_7,
721 half_width_close = chinese_8,
722}
723
724local function process(head,first,last)
725 if first ~= last then
726 local lastfont = nil
727 local previous = "start"
728 local last = nil
729 while true do
730 local upcoming = getnext(first)
731 local id = getid(first)
732 if id == glyph_code then
733 local current = getscriptstatus(first)
734 local action = injectors[previous]
735 if action then
736 action = action[current]
737 if action then
738 local font = getfont(first)
739 if font ~= lastfont then
740 lastfont = font
741 set_parameters(font,getscriptdata(first))
742 end
743 action(head,first)
744 end
745 end
746 previous = current
747 else
748 local p = getprev(first)
749 local n = upcoming
750 if p and n then
751 local pid = getid(p)
752 local nid = getid(n)
753 if pid == glyph_code and nid == glyph_code then
754 local pcjk = getscriptstatus(p)
755 local ncjk = getscriptstatus(n)
756 if not pcjk or not ncjk
757 or pcjk == "korean" or ncjk == "korean"
758 or pcjk == "other" or ncjk == "other"
759 or pcjk == "jamo_final" or ncjk == "jamo_initial"
760 or pcjk == "half_width_close" or ncjk == "half_width_open" then
761 previous = "start"
762 else
763 remove_node(head,first,true)
764 previous = pcjk
765
766
767 end
768 else
769 previous = "start"
770 end
771 else
772 previous = "start"
773 end
774 end
775 if upcoming == last then
776 break
777 else
778 first = upcoming
779 end
780 end
781 end
782end
783
784scripts.installmethod {
785 name = "hanzi",
786 injector = process,
787 datasets = {
788 default = {
789 inter_char_shrink_factor = 0.50,
790 inter_char_stretch_factor = 0.50,
791 inter_char_half_shrink_factor = 0.50,
792 inter_char_half_stretch_factor = 0.50,
793 inter_char_quarter_shrink_factor = 0.50,
794 inter_char_quarter_stretch_factor = 0.50,
795 inter_char_hangul_penalty = 50,
796 },
797 },
798}
799
800
801
802local japanese_0 = {
803}
804
805local japanese_1 = {
806 jamo_initial = korean_break,
807 korean = korean_break,
808 chinese = stretch_break,
809 hiragana = stretch_break,
810 katakana = stretch_break,
811 half_width_open = nobreak_stretch_break_autoshrink,
812 half_width_close = nobreak_stretch,
813 full_width_open = nobreak_stretch_break_shrink,
814 full_width_close = nobreak_stretch,
815 full_width_punct = nobreak_stretch,
816
817 non_starter = nobreak_stretch,
818 other = stretch_break,
819}
820
821local japanese_2 = {
822 jamo_initial = korean_break,
823 korean = stretch_break,
824 chinese = stretch_break,
825 hiragana = stretch_break,
826 katakana = stretch_break,
827 half_width_open = nobreak_stretch_break_autoshrink,
828 half_width_close = nobreak_stretch,
829 full_width_open = nobreak_stretch_break_shrink,
830 full_width_close = nobreak_stretch,
831 full_width_punct = japanese_before_full_width_punct,
832 hyphen = nobreak_stretch,
833 non_starter = nobreak_stretch,
834 other = stretch_break,
835}
836
837local japanese_3 = {
838 jamo_initial = korean_break,
839 korean = stretch_break,
840 chinese = stretch_break,
841 hiragana = stretch_break,
842 katakana = stretch_break,
843 half_width_open = nobreak_stretch_break_autoshrink,
844 half_width_close = nobreak_stretch,
845 full_width_open = nobreak_stretch_break_shrink,
846 full_width_close = nobreak_stretch,
847 full_width_punct = nobreak_stretch,
848
849 non_starter = nobreak_stretch,
850 other = stretch_break,
851}
852
853local japanese_4 = {
854
855
856
857
858
859 half_width_open = nobreak_autoshrink,
860 half_width_close = nil,
861 full_width_open = nobreak_shrink,
862 full_width_close = nobreak,
863 full_width_punct = nobreak,
864
865 non_starter = nobreak,
866
867}
868
869local japanese_5 = {
870 jamo_initial = stretch_break,
871 korean = stretch_break,
872 chinese = stretch_break,
873 hiragana = stretch_break,
874 katakana = stretch_break,
875 half_width_open = nobreak_stretch_break_autoshrink,
876 half_width_close = nobreak_stretch,
877 full_width_open = nobreak_stretch_break_shrink,
878 full_width_close = nobreak_stretch,
879 full_width_punct = nobreak_stretch,
880
881 non_starter = nobreak_stretch,
882 other = stretch_break,
883}
884
885local japanese_6 = {
886 jamo_initial = nobreak_stretch,
887 korean = nobreak_stretch,
888 chinese = nobreak_stretch,
889 hiragana = nobreak_stretch,
890 katakana = nobreak_stretch,
891 half_width_open = nobreak_stretch_break_autoshrink,
892 half_width_close = nobreak_stretch,
893 full_width_open = nobreak_stretch_break_shrink,
894 full_width_close = nobreak_stretch,
895 full_width_punct = nobreak_stretch,
896 hyphen = nobreak_stretch,
897 non_starter = nobreak_stretch,
898 other = nobreak_stretch,
899}
900
901local japanese_7 = {
902 jami_initial = nobreak_shrink_break_stretch,
903 korean = nobreak_shrink_break_stretch,
904 chinese = japanese_after_full_width_punct,
905 hiragana = japanese_after_full_width_punct,
906 katakana = japanese_after_full_width_punct,
907 half_width_open = nobreak_shrink_break_stretch_nobreak_autoshrink,
908 half_width_close = nobreak_shrink_nobreak_stretch,
909 full_width_open = japanese_between_full_close_open,
910 full_width_close = japanese_between_full_close_full_close,
911 full_width_punct = nobreak_shrink_nobreak_stretch,
912 hyphen = nobreak_shrink_break_stretch,
913 non_starter = nobreak_shrink_break_stretch,
914 other = nobreak_shrink_break_stretch,
915}
916
917local japanese_8 = {
918 jami_initial = nobreak_shrink_break_stretch,
919 korean = nobreak_autoshrink_break_stretch,
920 chinese = stretch_break,
921 hiragana = stretch_break,
922 katakana = stretch_break,
923 half_width_open = nobreak_autoshrink_break_stretch_nobreak_autoshrink,
924 half_width_close = nobreak_autoshrink_nobreak_stretch,
925 full_width_open = nobreak_autoshrink_break_stretch_nobreak_shrink,
926 full_width_close = nobreak_autoshrink_nobreak_stretch,
927 full_width_punct = nobreak_autoshrink_nobreak_stretch,
928 hyphen = nobreak_autoshrink_break_stretch,
929 non_starter = nobreak_autoshrink_break_stretch,
930 other = nobreak_autoshrink_break_stretch,
931}
932
933local injectors = {
934 jamo_final = japanese_1,
935 korean = japanese_1,
936 chinese = japanese_2,
937 hiragana = japanese_2,
938 katakana = japanese_2,
939 hyphen = japanese_3,
940 start = japanese_4,
941 other = japanese_5,
942 non_starter = japanese_5,
943 full_width_open = japanese_6,
944 half_width_open = japanese_6,
945 full_width_close = japanese_7,
946 full_width_punct = japanese_7,
947 half_width_close = japanese_8,
948}
949
950local function process(head,first,last)
951 if first ~= last then
952 local lastfont = nil
953 local previous = "start"
954 local last = nil
955 while true do
956 local upcoming = getnext(first)
957 local id = getid(first)
958 if id == glyph_code then
959 local current = getscriptstatus(first)
960 local action = injectors[previous]
961 if action then
962 action = action[current]
963 if action then
964 local font = getfont(first)
965 if font ~= lastfont then
966 lastfont = font
967 set_parameters(font,getscriptdata(first))
968 end
969 action(head,first)
970 end
971 end
972 previous = current
973
974
975
976 else
977 local p = getprev(first)
978 local n = upcoming
979 if p and n then
980 local pid = getid(p)
981 local nid = getid(n)
982 if pid == glyph_code and nid == glyph_code then
983 local pcjk = getscriptstatus(p)
984 local ncjk = getscriptstatus(n)
985 if not pcjk or not ncjk
986 or pcjk == "korean" or ncjk == "korean"
987 or pcjk == "other" or ncjk == "other"
988 or pcjk == "jamo_final" or ncjk == "jamo_initial"
989 or pcjk == "half_width_close" or ncjk == "half_width_open" then
990 previous = "start"
991 else
992 if id == glue_code then
993
994 local subtype = getsubtype(first)
995 if subtype == userskip_code or subtype == spaceskip_code or subtype == xspaceskip_code then
996
997 local w = getwidth(first)
998 local s = spacedata[getfont(p)]
999 if w == s then
1000 if trace_details then
1001 trace_detail_between(p,n,"space removed")
1002 end
1003 remove_node(head,first,true)
1004 end
1005 end
1006 end
1007 previous = pcjk
1008
1009
1010 end
1011 else
1012 previous = "start"
1013 end
1014 else
1015 previous = "start"
1016 end
1017 end
1018 if upcoming == last then
1019 break
1020 else
1021 first = upcoming
1022 end
1023 end
1024 end
1025end
1026
1027scripts.installmethod {
1028 name = "nihongo",
1029 injector = process,
1030 datasets = {
1031 default = {
1032 inter_char_shrink_factor = 0.50,
1033 inter_char_stretch_factor = 0.50,
1034 inter_char_half_shrink_factor = 0.50,
1035 inter_char_half_stretch_factor = 0.50,
1036 inter_char_quarter_shrink_factor = 0.25,
1037 inter_char_quarter_stretch_factor = 0.25,
1038 inter_char_hangul_penalty = 50,
1039 },
1040 },
1041}
1042 |