diff options
Diffstat (limited to 'Master/texmf-dist/tex/luatex/luatexja/ltj-ruby.lua')
-rw-r--r-- | Master/texmf-dist/tex/luatex/luatexja/ltj-ruby.lua | 184 |
1 files changed, 86 insertions, 98 deletions
diff --git a/Master/texmf-dist/tex/luatex/luatexja/ltj-ruby.lua b/Master/texmf-dist/tex/luatex/luatexja/ltj-ruby.lua index e2cb40d925b..685e19bb0b6 100644 --- a/Master/texmf-dist/tex/luatex/luatexja/ltj-ruby.lua +++ b/Master/texmf-dist/tex/luatex/luatexja/ltj-ruby.lua @@ -3,7 +3,7 @@ -- luatexbase.provides_module({ name = 'luatexja.ruby', - date = '2020-10-05', + date = '2020-10-30', description = 'Ruby annotation', }) luatexja.ruby = {} @@ -43,14 +43,7 @@ local id_pbox_w = 258 -- cluster which consists of a whatsit local attr_icflag = luatexbase.attributes['ltj@icflag'] -- ルビ処理用の attribute は他のやつの流用なので注意! -- 進入許容量 (sp) -local attr_ruby_maxprep = luatexbase.attributes['ltj@charclass'] -local attr_ruby_maxpostp = luatexbase.attributes['ltj@kcat0'] -local attr_ruby_maxmargin = luatexbase.attributes['ltj@kcat1'] -local attr_ruby_stretch = luatexbase.attributes['ltj@kcat2'] -local attr_ruby_mode = luatexbase.attributes['ltj@kcat3'] local attr_ruby_id = luatexbase.attributes['ltj@kcat4'] -- uniq id -local attr_ruby_intergap = luatexbase.attributes['ltj@kcat5'] -local attr_ruby_baseheight= luatexbase.attributes['ltj@kcat6'] local attr_ruby = luatexbase.attributes['ltj@rubyattr'] -- ルビ内部処理用,以下のようにノードによって使われ方が異なる -- * (whatsit) では JAglue 処理時に, @@ -260,17 +253,9 @@ local function texiface_low(rst, rtlr, rtlp) setfield(w, 'type', 110); setfield(w, 'user_id', RUBY_PRE) local wv = node_new(id_whatsit, sid_user) setfield(w, 'value', to_node(wv)) - setfield(wv, 'type', 100) - setfield(wv, 'value', floor(#rtlr)) + setfield(wv, 'type', 108) + setfield(wv, 'value', rst); rst.count = floor(#rtlr) setfield(wv, 'user_id', RUBY_PRE) -- dummy - set_attr(wv, attr_ruby, rst.rubyzw) - set_attr(wv, attr_ruby_maxmargin, rst.maxmargin) - set_attr(wv, attr_ruby_maxprep, rst.pre) - set_attr(wv, attr_ruby_maxpostp, rst.post) - set_attr(wv, attr_ruby_intergap, rst.intergap) - set_attr(wv, attr_ruby_baseheight, rst.baseheight) - set_attr(wv, attr_ruby_stretch, rst.stretch) - set_attr(wv, attr_ruby_mode, rst.mode) local n = wv for i = 1, #rtlr do _, n = insert_after(wv, n, rtlr[i]) @@ -314,13 +299,19 @@ end ---------------------------------------------------------------- -- r, p の中身のノードは再利用される -local function enlarge_parent(r, p, tmp_tbl, intmode) +local function enlarge_parent(r, p, tmp_tbl, no_begin, no_end) -- r: ルビ部分の格納された box,p: 同,親文字 local rwidth = getfield(r, 'width') local sumprot = rwidth - getfield(p, 'width') -- >0 local pre_intrusion, post_intrusion local ppre, pmid, ppost = tmp_tbl.ppre, tmp_tbl.pmid, tmp_tbl.ppost local mapre, mapost = tmp_tbl.mapre, tmp_tbl.mapost + local intmode = floor(tmp_tbl.mode/4)%4 + if no_begin then mapre = mapre + tmp_tbl.before_jfmgk end + if no_end then mapost = mapost + tmp_tbl.after_jfmgk end + if (tmp_tbl.mode%4 >=2) and (tmp.pre<0) and (tmp.post<0) then + mapre = min(mapre,mapost); mapost = mapre + end if intmode == 0 then -- とりあえず組んでから決める p = enlarge(p, rwidth, ppre, pmid, ppost, 0, 0) pre_intrusion = min(mapre, round(ppre*getfield(p, 'glue_set')*65536)) @@ -350,25 +341,26 @@ local function enlarge_parent(r, p, tmp_tbl, intmode) setfield(p, 'width', rwidth) local ps = getlist(p) setfield(ps, 'width', getfield(ps, 'width') - pre_intrusion) - return r, p, post_intrusion + local orig_post_intrusion = post_intrusion + if no_end then orig_post_intrusion = max(orig_post_intrusion - tmp_tbl.after_jfmgk, 0) end + return r, p, orig_post_intrusion end -- ルビボックスの生成(単一グループ) -- returned value: <new box>, <ruby width>, <post_intrusion> local max_margin -local function new_ruby_box(r, p, tmp_tbl) +local function new_ruby_box(r, p, tmp_tbl, no_begin, no_end) local post_intrusion = 0 local imode local ppre, pmid, ppost = tmp_tbl.ppre, tmp_tbl.pmid, tmp_tbl.ppost local mapre, mapost = tmp_tbl.mapre, tmp_tbl.mapost local rpre, rmid, rpost, rsmash - imode = floor(tmp_tbl.imode/0x100000); rsmash = (imode%2 ==1) + imode = floor(tmp_tbl.mode/0x100000); rsmash = (imode%2 ==1) imode = floor(imode/2); rpost = imode%8; imode = (imode-rpost)/8; rmid = imode%8; imode = (imode-rmid)/8; rpre = imode%8 if getfield(r, 'width') > getfield(p, 'width') then -- change the width of p - r, p, post_intrusion = enlarge_parent(r, p, tmp_tbl, - floor(tmp_tbl.imode/4)%4) + r, p, post_intrusion = enlarge_parent(r, p, tmp_tbl, no_begin, no_end) elseif getfield(r, 'width') < getfield(p, 'width') then -- change the width of r r = enlarge(r, getfield(p, 'width'), rpre, rmid, rpost, 0, 0) post_intrusion = 0 @@ -392,10 +384,10 @@ local function new_ruby_box(r, p, tmp_tbl) end local a, k = node_new(id_rule), node_new(id_kern, 1) setfield(a, 'width', 0); setfield(a, 'height', 0) - setfield(a, 'depth', 0); setfield(k, 'kern', tmp_tbl.rgap) + setfield(a, 'depth', 0); setfield(k, 'kern', tmp_tbl.intergap) insert_after(r, r, a); insert_after(r, a, k); insert_after(r, k, p); setfield(p, 'next', nil) - if tmp_tbl.bheight >= 0 then setfield(p, 'height', tmp_tbl.bheight) end + if tmp_tbl.baseheight >= 0 then setfield(p, 'height', tmp_tbl.baseheight) end a = node.direct.vpack(r); setfield(a, 'shift', 0) set_attr(a, attr_ruby, post_intrusion) if rsmash or getfield(a, 'height')<getfield(p, 'height') then @@ -416,10 +408,7 @@ local max_allow_pre, max_allow_post -- 中付き熟語ルビ,cmp containers -- 「文字の構成を考えた」やつはどうしよう -local pre_low_cal_box -do -local tmp_tbl = {} -pre_low_cal_box = function (w, cmp) +local function pre_low_cal_box(w, cmp) local rb = {} local pb = {} local kf = {} @@ -427,17 +416,15 @@ pre_low_cal_box = function (w, cmp) -- kf[cmp+i] : container i--cmp からなる行頭形 -- kf[2cmp+1] : 行中形 local wv = getfield(w, 'value') + local rst = getfield(wv, 'value') local mdt -- nt*: node temp local coef = {} -- 連立一次方程式の拡大係数行列 - local rtb = expand_3bits(has_attr(wv, attr_ruby_stretch)) - tmp_tbl.rgap = has_attr(wv, attr_ruby_intergap) - tmp_tbl.imode = has_attr(wv, attr_ruby_mode) - tmp_tbl.bheight = has_attr(wv, attr_ruby_baseheight) + local rtb = expand_3bits(rst.stretch) -- node list 展開・行末形の計算 local nt, nta, ntb = wv, nil, nil -- nt*: node temp - tmp_tbl.ppre, tmp_tbl.pmid, tmp_tbl.ppost = rtb[6], rtb[5], rtb[4] - tmp_tbl.mapre, tmp_tbl.mapost = max_allow_pre, 0 + rst.ppre, rst.pmid, rst.ppost = rtb[6], rtb[5], rtb[4] + rst.mapre, rst.mapost = max_allow_pre, 0 for i = 1, cmp do nt = node_next(nt); rb[i] = nt; nta = concat(nta, node_copy(nt)) nt = node_next(nt); pb[i] = nt; ntb = concat(ntb, node_copy(nt)) @@ -445,31 +432,31 @@ pre_low_cal_box = function (w, cmp) for j = 1, 2*i do coef[i][j] = 1 end for j = 2*i+1, 2*cmp+1 do coef[i][j] = 0 end kf[i], coef[i][2*cmp+2] - = new_ruby_box(node_copy(nta), node_copy(ntb), tmp_tbl) + = new_ruby_box(node_copy(nta), node_copy(ntb), rst, true, false) end node_free(nta); node_free(ntb) -- 行頭形の計算 local nta, ntb = nil, nil - tmp_tbl.ppre, tmp_tbl.pmid, tmp_tbl.ppost = rtb[9], rtb[8], rtb[7] - tmp_tbl.mapre, tmp_tbl.mapost = 0, max_allow_post + rst.ppre, rst.pmid, rst.ppost = rtb[9], rtb[8], rtb[7] + rst.mapre, rst.mapost = 0, max_allow_post for i = cmp,1,-1 do coef[cmp+i] = {} for j = 1, 2*i-1 do coef[cmp+i][j] = 0 end for j = 2*i, 2*cmp+1 do coef[cmp+i][j] = 1 end nta = concat(node_copy(rb[i]), nta); ntb = concat(node_copy(pb[i]), ntb) kf[cmp+i], coef[cmp+i][2*cmp+2] - = new_ruby_box(node_copy(nta), node_copy(ntb), tmp_tbl) + = new_ruby_box(node_copy(nta), node_copy(ntb), rst, false, true) end -- ここで,nta, ntb には全 container を連結した box が入っているので -- それを使って行中形を計算する. coef[2*cmp+1] = {} for j = 1, 2*cmp+1 do coef[2*cmp+1][j] = 1 end - tmp_tbl.ppre, tmp_tbl.pmid, tmp_tbl.ppost = rtb[3], rtb[2], rtb[1] - tmp_tbl.mapre, tmp_tbl.mapost = max_allow_pre, max_allow_post + rst.ppre, rst.pmid, rst.ppost = rtb[3], rtb[2], rtb[1] + rst.mapre, rst.mapost = max_allow_pre, max_allow_post kf[2*cmp+1], coef[2*cmp+1][2*cmp+2], post_intrusion_backup - = new_ruby_box(nta, ntb, tmp_tbl) + = new_ruby_box(nta, ntb, rst, true, true) -- w.value の node list 更新. local nt = wv @@ -483,7 +470,6 @@ pre_low_cal_box = function (w, cmp) end return coef end -end local first_whatsit do @@ -535,8 +521,9 @@ local function pre_high(ahead) local n = first_whatsit(head) while n do if getsubtype(n) == sid_user and getfield(n, 'user_id') == RUBY_PRE then - local nv = getfield(n, 'value') - max_allow_pre = has_attr(nv, attr_ruby_maxprep) or 0 + local nv = getfield(n, 'value') + local rst = getfield(nv, 'value') + max_allow_pre = rst.pre or 0 local atr = has_attr(n, attr_ruby) or 0 if max_allow_pre < 0 then if atr>0 then @@ -550,13 +537,12 @@ local function pre_high(ahead) end end post_intrusion_backup = 0 - max_allow_post = has_attr(nv, attr_ruby_maxpostp) or 0 - max_margin = has_attr(nv, attr_ruby_maxmargin) or 0 - local coef = pre_low_cal_box(n, getfield(nv, 'value')) + max_allow_post = rst.post or 0 + max_margin = rst.maxmargin or 0 + local coef = pre_low_cal_box(n, rst.count) local s = node_tail(nv) --ルビ文字 head, n = pre_low_app_node( - head, n, getfield(nv, 'value'), coef, - getfield(s, 'height'), getfield(s, 'depth') + head, n, rst.count, coef, getfield(s, 'height'), getfield(s, 'depth') ) else n = first_whatsit(node_next(n)) @@ -646,7 +632,7 @@ local function post_high_break(head) rs[1], rw = ha, nil; ha = node_next(ha) elseif i==2 then rw = ha - cmp = getfield(getfield(rw, 'value'), 'value') + cmp = getfield(getfield(rw, 'value'), 'value').count local hb, hc = node_remove(getlist(h), rw) setfield(h, 'head', hb); ha = hc else -- i>=3 @@ -678,7 +664,7 @@ local function post_high_hbox(ahead) rs[1], rw = ha, nil; ha = node_next(ha) elseif i==2 then rw = ha - cmp = getfield(getfield(rw, 'value'), 'value') + cmp = getfield(getfield(rw, 'value'), 'value').count head, ha = node_remove(head, rw) else -- i >= 3 rs[#rs+1] = ha; ha = node_next(ha) @@ -701,37 +687,38 @@ do elseif getfield(lp, 'user_id') == RUBY_PRE then Np.first, Np.nuc, Np.last = lp, lp, lp local lpv = getfield(lp, 'value') + local rst = getfield(lpv, 'value') local x = node_next(node_next(lpv)) Np.last_char = luatexja.jfmglue.check_box_high(Np, getlist(x), nil) if Nq.id ~=id_pbox_w then if type(Nq.char)=='number' then -- Nq is a JAchar - if has_attr(lpv, attr_ruby_maxprep) < 0 then -- auto + if rst.pre < 0 then -- auto local p = round((ltjs.table_current_stack[RIPRE + Nq.char] or 0) - *has_attr(lpv, attr_ruby)) - if has_attr(lpv, attr_ruby_mode)%2 == 0 then -- intrusion 無効 + *rst.rubyzw) + if rst.mode%2 == 0 then -- intrusion 無効 p = 0 end - set_attr(lpv, attr_ruby_maxprep, -p) + rst.pre = -p end if Nq.prev_ruby then set_attr(lp, attr_ruby, Nq.prev_ruby) end - elseif has_attr(lpv, attr_ruby_maxprep) < 0 then -- auto + elseif rst.pre < 0 then -- auto if Nq.char == 'parbdd' then local p = round((ltjs.table_current_stack[RIPRE-1] or 0) - *has_attr(lpv, attr_ruby)) + *rst.rubyzw) p = min(p, Nq.width) - if has_attr(lpv, attr_ruby_mode)%2 == 0 then -- intrusion 無効 + if rst.mode%2 == 0 then -- intrusion 無効 p = 0 end - set_attr(lpv, attr_ruby_maxprep, p) + rst.pre = p else - set_attr(lpv, attr_ruby_maxprep, 0) + rst.pre = 0 end end - elseif has_attr(lpv, attr_ruby_maxprep) < 0 then -- auto - set_attr(lpv, attr_ruby_maxprep, 0) + elseif rst.pre < 0 then -- auto + rst.pre = 0 end return Np else @@ -743,6 +730,16 @@ do end do + local FROM_JFM = luatexja.icflag_table.FROM_JFM + local KANJI_SKIP = luatexja.icflag_table.KANJI_SKIP + local function add_gk(t, index, p) + local ic = get_attr_icflag(p) + if ic and (ic>FROM_JFM) and (ic<KANJI_SKIP) then ic = FROM_JFM end + if t.intrude_jfmgk[ic] then + if getid(p)==id_kern then t[index] = t[index] + getfield(p, 'kern') + else t[index] = t[index] + getfield(p, 'width') end + end + end local RIPOST = luatexja.stack_table_index.RIPOST local function whatsit_after_callback(s, Nq, Np) if not s and getfield(Nq.nuc, 'user_id') == RUBY_PRE then @@ -752,44 +749,35 @@ do insert_before(Nq.nuc, Np.first, last_glue) Np.first = last_glue next_cluster_array[Nq.nuc] = last_glue -- ルビ処理用のグルー --- if Nq.gk then --- if type(Nq.gk)=="table" then --- for _,v in ipairs(Nq.gk) do luatexja.ext_show_node(node.direct.tonode(v), 'BBt> ', print) end --- else luatexja.ext_show_node(node.direct.tonode(Nq.gk), 'BBB> ', print) end --- end end local nqnv = getfield(Nq.nuc, 'value') + local rst = getfield(nqnv, 'value') + if Nq.gk then + if type(Nq.gk)=="table" then + for _,v in ipairs(Nq.gk) do add_gk(rst, 'before_jfmgk', v) end + else add_gk(rst, 'before_jfmgk', Nq.gk) end + end local x = node_next(node_next(nqnv)) - for i = 2, getfield(nqnv, 'value') do x = node_next(node_next(x)) end + for i = 2, rst.count do x = node_next(node_next(x)) end Nq.last_char = luatexja.jfmglue.check_box_high(Nq, getlist(x), nil) luatexja.jfmglue.after_hlist(Nq) if Np and Np.id ~=id_pbox_w and type(Np.char)=='number' then -- Np is a JAchar - local rm = has_attr(nqnv, attr_ruby_mode) - if has_attr(nqnv, attr_ruby_maxpostp) < 0 then -- auto + if rst.post < 0 then -- auto local p = round((ltjs.table_current_stack[RIPOST + Np.char] or 0) - *has_attr(nqnv, attr_ruby)) - if rm%2 == 0 then -- intrusion 無効 + *rst.rubyzw) + if rst.mode%2 == 0 then -- intrusion 無効 p = 0 end - if rm%4 >= 2 then - local q = has_attr(nqnv, attr_ruby_maxprep) - if q < p then p = q - elseif q > p then - set_attr(nqnv, attr_ruby_maxprep, p) - end - end - set_attr(nqnv, attr_ruby_maxpostp, p) + rst.post = p end Np.prev_ruby = has_attr(getfield(Nq.nuc, 'value'), attr_ruby_id) -- 前のクラスタがルビであったことのフラグ else -- 直前が文字以外 local nqnv = getfield(Nq.nuc, 'value') - if has_attr(nqnv, attr_ruby_maxpostp) < 0 then -- auto - set_attr(nqnv, attr_ruby_maxpostp, 0) - if has_attr(nqnv, attr_ruby_mode)%4 >= 2 then - set_attr(nqnv, attr_ruby_maxprep, 0) - end + local rst = getfield(nqnv, 'value') + if rst.post < 0 then -- auto + rst.post = 0 end end return true @@ -799,16 +787,16 @@ do end luatexbase.add_to_callback("luatexja.jfmglue.whatsit_after", whatsit_after_callback, "luatexja.ruby.np_info_after", 1) -end -if false then -- いまは off - local function w (s, Nq, Np) - if Np.gk then - if type(Np.gk)=="table" then - for _,v in ipairs(Np.gk) do luatexja.ext_show_node(node.direct.tonode(v), 'AAt> ', print) end - else luatexja.ext_show_node(node.direct.tonode(Np.gk), 'AAA> ', print) end - end - end - luatexbase.add_to_callback("luatexja.jfmglue.whatsit_last_minute", w, + local function w (s, Nq, Np) + if not s and getfield(Nq.nuc, 'user_id') == RUBY_PRE then + local rst = getfield(getfield(Nq.nuc, 'value'), 'value') + if Np.gk then + if type(Np.gk)=="table" then + for _,v in ipairs(Np.gk) do add_gk(rst, 'after_jfmgk', v) end + else add_gk(rst, 'after_jfmgk', Np.gk) end + end + end + end + luatexbase.add_to_callback("luatexja.jfmglue.whatsit_last_minute", w, "luatexja.ruby.np_info_last_minute", 1) end - |