OSDN Git Service

Added test17-totenwidth.{tex,pdf}
[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_glue  = node.id('glue')
10 local id_glue_spec = node.id('glue_spec')
11 local attr_icflag = luatexbase.attributes['ltj@icflag']
12 local PACKED = 2
13 local PROCESSED_BEGIN_FLAG = 16
14
15 local function get_attr_icflag(p)
16    return (node.has_attribute(p, attr_icflag) or 0) % PROCESSED_BEGIN_FLAG
17 end
18
19 -- box 内で伸縮された glue の合計値を計算
20 local function compute_total_stretched(p)
21   local go, gf, gs = p.glue_order, p.glue_set, p.glue_sign
22   if gs ~= 1 and gs ~= 2 then return 0 end
23   local a = 0
24   for q in node.traverse_id(id_glue, p.head) do
25     local qs = q.spec
26     if gs == 1 then -- stretching
27       if qs.stretch_order == go then a = a + qs.stretch end
28     else -- shrinking
29       if qs.shrink_order == go then a = a - qs.shrink end
30     end
31   end
32   return tex.round(a * gf)
33 end
34
35 function adjust_width_toten(head) 
36   if not head then return head end
37   for p in node.traverse_id(id_hlist, head) do
38     local t = node.tail(p.head) -- \rightskip glue
39     local x = node.prev(t)      -- 本当の行末の node を格納
40     if x.id == id_glue and x.subtype == 15 then
41       -- 段落最終行のときの補正
42       x = node.prev(node.prev(x))
43     end
44     if x.id == id_hlist and get_attr_icflag(x) == PACKED then
45        local xc = x.head
46        local xcs = tex.round(font.fonts[xc.font].size*0.5)
47        local xcc = unicode.utf8.char(xc.char)
48        if (xcc == ','  or xcc == '、' or xcc == '.'  or xcc == '。')
49           and xcs <= compute_total_stretched(p) then
50          local ag  = node.new(id_glue) -- additional glue
51          local ags = node.new(id_glue_spec)
52          ag.spec, ags.width = ags, xcs
53          ags.shrink, ags.stretch, ags.shrink_order, ags.stretch_order = 0, 0, 0, 0
54          node.insert_after(p.head, x, ag)
55          local f = node.hpack(p.head, p.width, 'exactly')
56          f.head, p.glue_set, p.glue_sign, p.glue_order 
57            = nil, f.glue_set, f.glue_sign, f.glue_order
58          node.free(f)
59        end
60     end
61   end
62   return head
63 end
64
65 luatexbase.add_to_callback('post_linebreak_filter', 
66   adjust_width_toten, 'Adjust width of toten', 100)
67 \end{luacode}
68
69 \begin{document}
70 \parindent0pt
71 \leavevmode
72 \vrule\setbox0=\vbox{\hsize=20\zw 
73 0123456789あいうえおかきくけ,%
74 0123456789あいうえおかきくけ.%
75 0123456789あいうえおかきく\hskip .25\zw こ.%
76 0123456789あいうえおかきく\hskip .5 \zw け,%
77 012345678\hskip0\zw 9あいうえおかきくけ,%
78
79 0123456789あいうえおかきくけこ%
80 }\copy0\vrule
81
82 \directlua{luatexja.ext_show_node_list(tex.box[0], '  ', print)}
83
84 \end{document}