OSDN Git Service

more unicode library -> utf
[luatex-ja/luatexja.git] / test / test17-totenwidth.tex
1 %#!lualatex
2
3 %% 行末の句読点の位置によって,全角取りか半角取りかを自動的に調整する
4 %% 仕様:全調整量が二分以上なら,全角取りにする
5 \documentclass{article}
6 \usepackage{luatexja,luacode}
7 \begin{luacode}
8 local id_hlist = node.id('hlist')
9 local id_penalty = node.id('penalty')
10 local id_glue  = node.id('glue')
11 local id_glue_spec = node.id('glue_spec')
12 local attr_icflag = luatexbase.attributes['ltj@icflag']
13 local PACKED = luatexja.icflag_table.PACKED
14 local PROCESSED_BEGIN_FLAG = luatexja.icflag_table.PROCESSED_BEGIN_FLAG
15
16 local function get_attr_icflag(p)
17    return (node.has_attribute(p, attr_icflag) or 0) % PROCESSED_BEGIN_FLAG
18 end
19
20 -- box 内で伸縮された glue の合計値を計算
21 local function compute_total_stretched(p)
22   local go, gf, gs = p.glue_order, p.glue_set, p.glue_sign
23   if gs ~= 1 and gs ~= 2 then return 0 end
24   local a = 0
25   for q in node.traverse_id(id_glue, p.head) do
26     local qs = q
27     if gs == 1 then -- stretching
28       if qs.stretch_order == go then a = a + qs.stretch end
29     else -- shrinking
30       if qs.shrink_order == go then a = a - qs.shrink end
31     end
32   end
33   return tex.round(a * gf)
34 end
35
36 function adjust_width_toten(head) 
37   if not head then return head end
38   for p in node.traverse_id(id_hlist, head) do repeat
39     local t = node.tail(p.head) -- \rightskip glue
40     local x = node.prev(t)      -- 本当の行末の node を格納
41     if not x then break end
42     if x.id == id_glue and x.subtype == 15 then
43       -- 段落最終行のときの補正
44       x = node.prev(node.prev(x))
45     end
46     while x do
47       if x.id == id_penalty then x = node.prev(x) else break end
48     end
49     if x.id == id_hlist and get_attr_icflag(x) == PACKED then
50        local xc = x.head
51        local xcs = tex.round(font.fonts[xc.font].size*0.5)
52        -- 句読点の最大補正幅
53        local xcc = utf.char(xc.char)
54        local cts = compute_total_stretched(p)
55        if (xcc == ','  or xcc == '、' or xcc == '.'  or xcc == '。') and cts>=0 then
56          local ag  = node.new(id_glue) -- additional glue
57          ag.width = math.min(xcs, cts)
58          ag.shrink, ag.stretch, ag.shrink_order, ag.stretch_order = 0, 0, 0, 0
59          node.insert_after(p.head, x, ag)
60          local f = node.hpack(p.head, p.width, 'exactly')
61          f.head, p.glue_set, p.glue_sign, p.glue_order 
62            = nil, f.glue_set, f.glue_sign, f.glue_order
63          node.free(f)
64        end
65     end
66   until true end
67   return head
68 end
69
70 luatexbase.add_to_callback('post_linebreak_filter', 
71   adjust_width_toten, 'Adjust width of toten', 100)
72 \end{luacode}
73
74 \begin{document}
75 \parindent0pt
76 \leavevmode
77 \vrule\setbox0=\vbox{\hsize=20\zw 
78 012345678\hskip-0.25\zw 9あいうえおかきくけ,\break
79 012345678\hskip0\zw 9あいうえおかきくけ,\break
80 012345678\hskip0.25\zw 9あいうえおかきくけ,\break
81 012345678\hskip0.5\zw 9あいうえおかきくけ,\break
82 012345678\hskip0.75\zw 9あいうえおかきくけ,\break
83 012345678\hskip1\zw 9あいうえおかきくけ,\break
84
85 0123456789あいうえおかきくけこ%
86 }\copy0\vrule
87
88 \end{document}