OSDN Git Service

優先度付き調整処理のテスト (test17-priority.tex)
[luatex-ja/luatexja.git] / test / test17-priority.tex
1 %#!lualatex
2
3 %% 行末の句読点の位置によって,全角取りか半角取りかを自動的に調整する
4 %% 仕様:全調整量が二分以上なら,全角取りにする
5 \documentclass{article}
6 \usepackage{luatexja,luacode,xcolor}
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 local FROM_JFM = 4
15 local KANJI_SKIP = 6
16 local XKANJI_SKIP = 7
17
18 local function get_attr_icflag(p)
19    return (node.has_attribute(p, attr_icflag) or 0) % PROCESSED_BEGIN_FLAG
20 end
21
22 -- box 内で伸縮された glue の合計値を計算
23
24 local function get_stretched(q, go, gs)
25   local qs = q.spec
26   if not qs.writable then return 0 end
27   if gs == 1 then -- stretching
28     if qs.stretch_order == go then return qs.stretch end
29   else -- shrinking
30     if qs.shrink_order == go then return qs.shrink end
31   end
32 end
33
34 local function get_total_stretched(p)
35   local go, gf, gs = p.glue_order, p.glue_set, p.glue_sign
36   local res = {
37     other = 0, xkanji = 0, jfm = 0, kanji = 0, 
38     glue_set = gf, glue_sign = gs
39   }
40   if go ~= 0 then return nil end
41   if gs ~= 1 and gs ~= 2 then return res end
42   for q in node.traverse_id(id_glue, p.head) do
43     local a, ic = get_stretched(q, go, gs), get_attr_icflag(q)
44     if     ic == KANJI_SKIP  then res.kanji  = res.kanji + a
45     elseif ic == XKANJI_SKIP then res.xkanji = res.xkanji + a
46     elseif ic == FROM_JFM    then res.jfm    = res.jfm + a
47     else                          res.other  = res.other + a
48     end
49   end
50   return res
51 end
52
53 local function clear_stretch(p, ic)
54   for q in node.traverse_id(id_glue, p.head) do
55     if get_attr_icflag(q) == ic then
56       local qs = q.spec
57       if qs.writable then
58         qs.stretch_order, qs.shrink_order, qs.stretch, qs.shrink = 0, 0, 0, 0
59       end
60     end
61   end
62 end
63
64 local function set_stretch(p, after, before, ic)
65   if before > 0 then
66     print (ic, before, after)
67     local ratio = after/before
68     for q in node.traverse_id(id_glue, p.head) do
69       if get_attr_icflag(q) == ic then
70         local qs = q.spec
71         if qs.writable then
72           qs.stretch, qs.shrink = qs.stretch*ratio, qs.shrink*ratio
73         end
74       end
75     end    
76   end
77 end
78
79 function adjust_width(head) 
80   if not head then return head end
81   for p in node.traverse_id(id_hlist, head) do
82     local res = get_total_stretched(p)
83     if res then
84       -- 調整量の合計
85       local total = tex.round((res.other + res.xkanji + res.jfm + res.kanji) * res.glue_set)
86       print('before: ', p.glue_set, p.glue_sign, p.glue_order )
87       print(total, res.other, res.xkanji, res.jfm, res.kanji)
88       if total <= res.other then -- 和文処理グルー以外で足りる
89         clear_stretch(p, KANJI_SKIP)
90         clear_stretch(p, XKANJI_SKIP)
91         clear_stretch(p, FROM_JFM)
92         local f = node.hpack(p.head, p.width, 'exactly')
93         f.head, p.glue_set, p.glue_sign, p.glue_order 
94            = nil, f.glue_set, f.glue_sign, f.glue_order
95         node.free(f)
96       else
97         total = total - res.other
98         if total <= res.jfm then -- JFMグルーだけで良い
99           clear_stretch(p, KANJI_SKIP)
100           clear_stretch(p, XKANJI_SKIP)
101           set_stretch(p, total,res.jfm, FROM_JFM)
102           local f = node.hpack(p.head, p.width, 'exactly')
103           f.head, p.glue_set, p.glue_sign, p.glue_order 
104              = nil, f.glue_set, f.glue_sign, f.glue_order
105           node.free(f)
106         else
107           total = total - res.jfm
108           if total <= res.xkanji then -- xkanjiskip まで
109             clear_stretch(p, KANJI_SKIP)
110             set_stretch(p, total,res.xkanji, XKANJI_SKIP)
111             local f = node.hpack(p.head, p.width, 'exactly')
112             f.head, p.glue_set, p.glue_sign, p.glue_order 
113                = nil, f.glue_set, f.glue_sign, f.glue_order
114             node.free(f)
115           else
116             total = total - res.xkanji
117             if total <= res.kanji then -- kanjiskip まで
118               set_stretch(p, total,res.kanji, KANJI_SKIP)
119               local f = node.hpack(p.head, p.width, 'exactly')
120               f.head, p.glue_set, p.glue_sign, p.glue_order 
121                  = nil, f.glue_set, f.glue_sign, f.glue_order
122               node.free(f)
123             else
124               -- glue_set > 1 なので,どうしようもない
125             end
126           end
127         end
128       end
129     print('after:  ', p.glue_set, p.glue_sign, p.glue_order )
130     end
131   end
132   return head
133 end
134
135
136 \end{luacode}
137
138 \def\sq{\hbox to 1\zw{\hss\fboxsep=-.5\fboxrule\fbox{ }\hss}}
139 \def\sb{\hbox to 1\zw{\hss\fboxsep=-.5\fboxrule\fbox{■}\hss}}
140 \newbox\gridbox
141 \setbox\gridbox=\hbox to 20\zw{\sq\sq\sq\sq\sb\sq\sq\sq\sq\sb\sq\sq\sq\sq\sb\sq\sq\sq\sq\sb}
142 \def\outbox#1{%
143   \leavevmode\hbox to 2em{\tt #1\hss}\vrule
144   \textcolor{cyan!50!white}{\copy\gridbox}\hskip-20\zw\copy0\vrule\par
145 }
146
147 \def\DisableCB{\directlua{luatexbase.remove_from_callback('post_linebreak_filter', 'Adjust width')}}
148 \def\EnableCB{\directlua{luatexbase.add_to_callback('post_linebreak_filter', adjust_width, 'Adjust width', 100)}}
149
150 \long\def\testbox#1{%
151   \EnableCB\setbox0=\vbox{\hsize=20\zw\parfillskip0pt#1}\outbox{ON}\par
152   \DisableCB\setbox0=\vbox{\hsize=20\zw\parfillskip0pt#1}\outbox{OFF}\par
153 }
154
155 \parindent0pt
156 \begin{document}
157 {\tt kanjiskip: \ltjgetparameter{kanjiskip}
158
159 \ltjsetparameter{xkanjiskip=.25\zw plus .25\zw minus -.125\zw}
160 xkanjiskip: \ltjgetparameter{xkanjiskip}}
161
162 \testbox{%
163 あいうえおかきくけこさしすせそたちつてと
164 }
165
166 \testbox{%
167 あいうえおかきくけこ「「さしすせそたちつて
168 }
169
170 \testbox{%
171 あいうえおかきA B C Dこさ\texttt{DO i=1,10}『
172 }
173
174 \testbox{%
175 「\texttt{\textbackslash expandafter}ユーザの集い」が開催された
176 }
177
178 \testbox{%
179 あいうえおきくけこ「」さ123456そたちつて
180 }
181
182 \def\pTeX{p\kern-.2em\TeX}
183 \testbox{%
184 日本では\pTeX,p\LaTeX がよく使われている。
185 }
186 \end{document}