OSDN Git Service

l_step: ignore alignment
[luatex-ja/luatexja.git] / src / ltj-lineskip.lua
1 --
2 -- ltj-lineskip.lua
3 --
4 luatexja.load_module('base'); local ltjb = luatexja.base
5 luatexja.load_module('direction'); local ltjd = luatexja.direction
6 luatexja.lineskip = luatexja.lineskip or {}
7
8 local to_direct = node.direct.todirect
9 local ltjl = luatexja.lineskip
10 local id_glue = node.id('glue')
11 local id_hlist = node.id('hlist')
12 local setfield = node.direct.setfield
13 local getfield = node.direct.getfield
14 local getlist = node.direct.getlist
15 local node_new = node.direct.new
16 local node_prev = node.direct.getprev
17 local node_next = node.direct.getnext
18 local getid = node.direct.getid
19 local getsubtype = node.direct.getsubtype
20
21 local node_getglue = node.getglue
22 local setglue = node.direct.setglue
23 local function copy_glue (new_glue, old_glue, subtype, new_w)
24    setfield(new_glue, 'subtype', subtype)
25    local w,st,sp,sto,spo = node_getglue(old_glue)
26    setglue(new_glue, new_w or w, st, sp, sto, spo)
27 end
28 ltjl.copy_glue = copy_glue
29
30 function ltjl.p_dummy(before, after)
31    return nil, 0
32 end
33 function ltjl.l_dummy(dist, g, adj, normal, bw, loc)
34    if dist < tex.lineskiplimit then
35       copy_glue(g, tex.lineskip, 1, tex.lineskip.width + adj)
36    else
37       copy_glue(g, tex.baselineskip, 2, normal)
38    end
39 end
40
41 local ltj_profiler, ltj_skip = ltjl.p_dummy, ltjl.l_dummy
42 function ltjl.setting(profiler, skip_method)
43    ltj_profiler = ltjl['p_'..tostring(profiler)] or ltjl.p_dummy
44    ltj_skip = ltjl['l_'..tostring(skip_method)] or ltjl.l_dummy
45 end
46
47 do
48    local traverse_id = node.direct.traverse_id
49    local function adjust_glue(nh)
50       local h = to_direct(nh)
51       local bw = tex.baselineskip.width
52       for x in traverse_id(id_glue, h) do
53         local xs = getsubtype(x)
54         if (xs==1) or (xs==2) then
55            local p, n = node_prev(x), node_next(x)
56            if p then
57               local pid = getid(p)
58               while (12<=pid) and (pid<=14) and node_prev(p) do p = node_prev(p); pid = getid(p) end
59               if pid==id_hlist and getid(n)==id_hlist then
60                 local normal = bw - getfield(p, 'depth') - getfield(n, 'height')
61                 local lmin, adj = ltj_profiler(p, n, false, bw)
62                 ltj_skip(lmin or normal, x, adj, normal, bw)
63               end
64            end
65         end
66       end
67       return true
68    end
69    ltjb.add_to_callback('post_linebreak_filter', 
70       adjust_glue, 'ltj.lineskip', 10000)
71 end
72
73 do
74    local make_dir_whatsit = luatexja.direction.make_dir_whatsit
75    local get_dir_count = luatexja.direction.get_dir_count
76    local node_write = node.direct.write
77
78    local function dir_adjust_append_vlist(b, loc, prev, mirrored)
79       local old_b = to_direct(b)
80       local new_b = loc=='box' and 
81          make_dir_whatsit(old_b, old_b, get_dir_count(), 'append_vlist') or old_b      
82       if prev > -65536000 then
83          local bw = tex.baselineskip.width
84          local normal = bw - prev 
85             - getfield(new_b, mirrored and 'depth' or 'height')
86          local lmin, adj = nil, 0
87          local tail = to_direct(tex.nest[tex.nest.ptr].tail)
88          if tail and getid(tail)==id_glue and getsubtype(tail)==3 then
89             tail = node_prev(tail)
90          end
91          if tail then
92             if getid(tail)==id_hlist and getid(new_b)==id_hlist then
93                if getfield(tail, 'depth')==prev then 
94                   lmin, adj = ltj_profiler(tail, new_b, mirrored, bw)
95                end
96             end
97          end
98          local g = node_new(id_glue)
99          ltj_skip(lmin or normal, g, adj, normal, bw, loc)
100          node_write(g)
101       end
102       node_write(new_b)
103       tex.prevdepth = getfield(new_b, mirrored and 'height' or 'depth')
104       return nil -- do nothing on tex side
105    end
106    ltjb.add_to_callback('append_to_vlist_filter',
107                         dir_adjust_append_vlist,
108                         'ltj.lineskip', 10000)
109 end
110