4 luatexbase.provides_module({
5 name = 'luatexja.adjust',
8 description = 'Advanced line adjustment for LuaTeX-ja',
10 module('luatexja.adjust', package.seeall)
12 local id_hlist = node.id('hlist')
13 local id_glue = node.id('glue')
14 local id_glue_spec = node.id('glue_spec')
15 local attr_icflag = luatexbase.attributes['ltj@icflag']
20 local XKANJI_SKIP = 10
22 local priority_table = {
32 local PROCESSED_BEGIN_FLAG = 32
33 local function get_attr_icflag(p)
34 return (node.has_attribute(p, attr_icflag) or 0) % PROCESSED_BEGIN_FLAG
37 -- box 内で伸縮された glue の合計値を計算
39 local function get_stretched(q, go, gs)
41 if not qs.writable then return 0 end
42 if gs == 1 then -- stretching
43 if qs.stretch_order == go then return qs.stretch end
45 if qs.shrink_order == go then return qs.shrink end
49 local function get_total_stretched(p)
50 local go, gf, gs = p.glue_order, p.glue_set, p.glue_sign
53 glue_set = gf, name = (gs==1) and 'stretch' or 'shrink'
55 for i=1,#priority_table do res[priority_table[i]]=0 end
56 if go ~= 0 then return nil end
57 if gs ~= 1 and gs ~= 2 then return res end
58 for q in node.traverse_id(id_glue, p.head) do
59 local a, ic = get_stretched(q, go, gs), get_attr_icflag(q)
61 if type(res[ic]) == 'number' then res[ic] = res[ic] + a
62 else res[0] = res[0] + a
68 local function clear_stretch(p, ic, name)
69 --print('clear ' .. ic)
70 for q in node.traverse_id(id_glue, p.head) do
71 if get_attr_icflag(q) == ic then
74 qs[name..'_order'], qs[name] = 0, 0
80 local function set_stretch(p, after, before, ic, name)
82 --print (ic, before, after)
83 local ratio = after/before
84 for q in node.traverse_id(id_glue, p.head) do
85 if get_attr_icflag(q) == ic then
87 if qs.writable and qs[name..'_order'] == 0 then
88 qs[name] = qs[name]*ratio
96 function adjust_width(head)
97 if not head then return head end
98 for p in node.traverse_id(id_hlist, head) do
99 local res = get_total_stretched(p)
100 --print(table.serialize(res))
104 for i,v in pairs(res) do
105 if type(i)=='number' then
108 end; total = tex.round(total * res.glue_set)
109 if total <= res[0] then -- 和文処理グルー以外で足りる
110 for _,v in pairs(priority_table) do clear_stretch(p, v, res.name) end
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
116 total = total - res[0]
117 for i = 1, #priority_table do
118 local v = priority_table[i]
119 if total <= res[v] then
120 for j = i+1,#priority_table do
121 clear_stretch(p, priority_table[j], res.name)
123 set_stretch(p, total, res[v], v, res.name)
124 local f = node.hpack(p.head, p.width, 'exactly')
125 f.head, p.glue_set, p.glue_sign, p.glue_order
126 = nil, f.glue_set, f.glue_sign, f.glue_order
128 --print(p.glue_set, p.glue_sign, p.glue_order)
131 total = total - res[v]