X-Git-Url: http://git.osdn.jp/view?a=blobdiff_plain;f=src%2Fltj-jfmglue.lua;h=7c5ba8661aa040079e782d9413430f119ffcd9ee;hb=eb118f3e5ea0852407b5261817700401699528b9;hp=b080005189959a16660e568b592c1a1ffcda29f4;hpb=c7058402b4897aeb375eac689126792230877344;p=luatex-ja%2Fluatexja.git diff --git a/src/ltj-jfmglue.lua b/src/ltj-jfmglue.lua index b080005..7c5ba86 100644 --- a/src/ltj-jfmglue.lua +++ b/src/ltj-jfmglue.lua @@ -3,7 +3,7 @@ -- luatexbase.provides_module({ name = 'luatexja.jfmglue', - date = '2015/01/13', + date = '2015/05/03', description = 'Insertion process of JFM glues and kanjiskip', }) module('luatexja.jfmglue', package.seeall) @@ -66,7 +66,7 @@ local id_box_like = 256 -- vbox, shifted hbox local id_pbox = 257 -- already processed nodes (by \unhbox) local id_pbox_w = 258 -- cluster which consists of a whatsit local sid_user = node.subtype('user_defined') -local lang_ja = token.create('ltj@@japanese')[2] +local lang_ja = luatexja.lang_ja local sid_start_link = node.subtype('pdf_start_link') local sid_start_thread = node.subtype('pdf_start_thread') @@ -76,21 +76,15 @@ local sid_end_thread = node.subtype('pdf_end_thread') local ITALIC = luatexja.icflag_table.ITALIC local PACKED = luatexja.icflag_table.PACKED local KINSOKU = luatexja.icflag_table.KINSOKU +local FROM_JFM = luatexja.icflag_table.FROM_JFM local PROCESSED = luatexja.icflag_table.PROCESSED local IC_PROCESSED = luatexja.icflag_table.IC_PROCESSED local BOXBDD = luatexja.icflag_table.BOXBDD local PROCESSED_BEGIN_FLAG = luatexja.icflag_table.PROCESSED_BEGIN_FLAG local attr_icflag = luatexbase.attributes['ltj@icflag'] -local kanji_skip = node_new(id_glue) -local xkanji_skip = node_new(id_glue) -do - local KANJI_SKIP = luatexja.icflag_table.KANJI_SKIP - local XKANJI_SKIP = luatexja.icflag_table.XKANJI_SKIP - set_attr(kanji_skip, attr_icflag, KANJI_SKIP) - set_attr(xkanji_skip, attr_icflag, XKANJI_SKIP) -end - +local kanji_skip +local xkanji_skip local table_current_stack local list_dir local capsule_glyph @@ -228,6 +222,7 @@ local function check_box(box_ptr, box_end) last_char = s; found_visible_node = true else if getfield(p, 'shift')==0 then + last_char = nil if check_box(getlist(p), nil) then found_visible_node = true end else find_first_char = false; last_char = nil @@ -287,12 +282,6 @@ local calc_np do local traverse = Dnode.traverse -local function set_attr_icflag_processed(p) - if get_attr_icflag(p)<= ITALIC then - set_attr(p, attr_icflag, PROCESSED) - end -end - local function check_next_ickern(lp) if lp and getid(lp) == id_kern and ITALIC == get_attr_icflag(lp) then set_attr(lp, attr_icflag, IC_PROCESSED) @@ -307,9 +296,13 @@ local function calc_np_pbox(lp, last) Np.first = Np.first or lp; Np.id = id_pbox set_attr(lp, attr_icflag, get_attr_icflag(lp)); while lp ~=last and (lpa>=PACKED) and (lpa10000 then a = 10000 end setfield(p, 'penalty', a) head = insert_before(head, Np.first, p) Bp[1]=p; + set_attr(p, attr_icflag, KINSOKU) end else for _, v in pairs(Bp) do add_penalty(v,a) end end @@ -668,11 +663,12 @@ local function handle_penalty_always(post, pre, g) local a = (pre or 0) + (post or 0) if #Bp == 0 then if not (g and getid(g)==id_glue) or a~=0 then - local p = node_copy(pen_skel) + local p = node_new(id_penalty) if a<-10000 then a = -10000 elseif a>10000 then a = 10000 end setfield(p, 'penalty', a) head = insert_before(head, Np.first, p) Bp[1]=p + set_attr(p, attr_icflag, KINSOKU) end else for _, v in pairs(Bp) do add_penalty(v,a) end end @@ -682,36 +678,30 @@ local function handle_penalty_suppress(post, pre, g) local a = (pre or 0) + (post or 0) if #Bp == 0 then if g and getid(g)==id_glue then - local p = node_copy(pen_skel) + local p = node_new(id_penalty) setfield(p, 'penalty', 10000); head = insert_before(head, Np.first, p) Bp[1]=p + set_attr(p, attr_icflag, KINSOKU) end else for _, v in pairs(Bp) do add_penalty(v,a) end end end -- 和文文字間の JFM glue を node 化 -local new_jfm_glue -do - local FROM_JFM = luatexja.icflag_table.FROM_JFM - local glue_skel = {} - for i=FROM_JFM-2,FROM_JFM+2 do - glue_skel[i]= node_new(id_glue); set_attr(glue_skel[i], attr_icflag, i) - end - function new_jfm_glue(m, bc, ac) - -- bc, ac: char classes - local g = m.char_type[bc][ac] - if g then - if g[1] then - local f = node_copy(glue_skel[g[4]]) - setfield(f, 'spec', node_copy(g[2])) - return f, g[3] - else - return node_copy(g[2]), g[3] - end +local function new_jfm_glue(mc, bc, ac) +-- bc, ac: char classes + local g = mc[bc][ac] + if g then + if g[1] then + local f = node_new(id_glue) + set_attr(f, attr_icflag, g.priority) + setfield(f, 'spec', node_copy(g[2])) + return f, g.ratio, g.kanjiskip_natural, g.kanjiskip_stretch, g.kanjiskip_shrink + else + return node_copy(g[2]), g.ratio, false, false, false end - return nil, 0 end + return false, 0 end -- Nq.last (kern w) .... (glue/kern g) Np.first @@ -724,50 +714,6 @@ end -------------------- 和文文字間空白量の決定 -local null_skip_table = {0, 0, 0} --- get kanjiskip -local get_kanjiskip -local get_kanjiskip_normal, get_kanjiskip_jfm -do - local KANJI_SKIP = luatexja.icflag_table.KANJI_SKIP - local KANJI_SKIP_JFM = luatexja.icflag_table.KANJI_SKIP_JFM - get_kanjiskip_normal = function () - if Np.auto_kspc or Nq.auto_kspc then - return node_copy(kanji_skip) - else - local g = node_copy(zero_glue) - set_attr(g, attr_icflag, KANJI_SKIP) - return g - end - end - - get_kanjiskip_jfm = function () - local g - if Np.auto_kspc or Nq.auto_kspc then - g = node_new(id_glue); --copy_attr(g, Nq.nuc) - local gx = node_new(id_glue_spec); - setfield(gx, 'stretch_order', 0); setfield(gx, 'shrink_order', 0) - local pm, qm = Np.met, Nq.met - local bk = qm.kanjiskip or null_skip_table - if (pm.char_type==qm.char_type) and (qm.var==pm.var) then - setfield(gx, 'width', bk[1]) - setfield(gx, 'stretch', bk[2]) - setfield(gx, 'shrink', bk[3]) - else - local ak = pm.kanjiskip or null_skip_table - setfield(gx, 'width', round(diffmet_rule(bk[1], ak[1]))) - setfield(gx, 'stretch', round(diffmet_rule(bk[2], ak[2]))) - setfield(gx, 'shrink', -round(diffmet_rule(-bk[3], -ak[3]))) - end - setfield(g, 'spec', gx) - else - g = node_copy(zero_glue) - end - set_attr(g, attr_icflag, KANJI_SKIP_JFM) - return g - end -end - local calc_ja_ja_aux do local bg_ag = 2*id_glue - id_glue @@ -775,12 +721,13 @@ do local bk_ag = 2*id_kern - id_glue local bk_ak = 2*id_kern - id_kern - calc_ja_ja_aux = function (gb,ga, db, da) - local rbb, rab = 0.5*(1-db), 0.5*(1-da) -- 「前の文字」由来のグルーの割合 - local rba, raa = 0.5*(1+db), 0.5*(1+da) -- 「前の文字」由来のグルーの割合 + local function blend_diffmet(b, a, rb, ra) + return round(diffmet_rule((1-rb)*b+rb*a, (1-ra)*b+ra*a)) + end + calc_ja_ja_aux = function (gb, ga, db, da) if diffmet_rule ~= math.two_pleft and diffmet_rule ~= math.two_pright and diffmet_rule ~= math.two_paverage then - rbb, rab, rba, raa = 1,0,0,1 + db, da = 0, 1 end if not gb then if ga then @@ -794,126 +741,234 @@ do if k == bg_ag then local bs, as = getfield(gb, 'spec'), getfield(ga, 'spec') -- 両方とも glue. - local bd, ad = getfield(bs, 'width'), getfield(as, 'width') - setfield(bs, 'width', round(diffmet_rule(rbb*bd + rba*ad, rab*bd + raa*ad))) - bd, ad = getfield(bs, 'stretch'), getfield(as, 'stretch') - setfield(bs, 'stretch', round(diffmet_rule(rbb*bd + rba*ad, rab*bd + raa*ad))) - bd, ad = getfield(bs, 'shrink'), getfield(as, 'shrink') - setfield(bs, 'shrink', -round(diffmet_rule(-rbb*bd - rba*ad, -rab*bd - raa*ad))) + setfield(bs, 'width', blend_diffmet( + getfield(bs, 'width'), getfield(as, 'width'), db, da)) + setfield(bs, 'stretch', blend_diffmet( + getfield(bs, 'stretch'), getfield(as, 'stretch'), db, da)) + setfield(bs, 'shrink', -blend_diffmet( + -getfield(bs, 'shrink'), -getfield(as, 'shrink'), db, da)) node_free(ga) return gb elseif k == bk_ak then -- 両方とも kern. - local bd, ad = getfield(gb, 'kern'), getfield(ga, 'kern') - setfield(gb, 'kern', round(diffmet_rule(rbb*bd + rba*ad, rab*bd + raa*ad))) + setfield(gb, 'kern', blend_diffmet( + getfield(gb, 'kern'), getfield(ga, 'kern'), db, da)) node_free(ga) return gb elseif k == bk_ag then local as = getfield(ga, 'spec') -- gb: kern, ga: glue - local bd, ad = getfield(gb, 'kern'), getfield(as, 'width') - setfield(as, 'width', round(diffmet_rule(rbb*bd + rba*ad, rab*bd + raa*ad))) - ad = getfield(as, 'stretch') - setfield(bs, 'stretch', round(diffmet_rule(rba*ad, raa*ad))) - ad = getfield(as, 'shrink') - setfield(bs, 'shrink', -round(diffmet_rule(-rba*ad, -raa*ad))) + setfield(as, 'width', blend_diffmet( + getfield(gb, 'kern'), getfield(as, 'width'), db, da)) + setfield(as, 'stretch', blend_diffmet( + 0, getfield(as, 'stretch'), db, da)) + setfield(as, 'shrink', -blend_diffmet( + 0, -getfield(as, 'shrink'), db, da)) node_free(gb) - return ga + return ga, 0, 0, 0 else local bs = getfield(gb, 'spec') -- gb: glue, ga: kern - local bd, ad = getfield(bs, 'width'), getfield(ga, 'kern') - setfield(bs, 'width', round(diffmet_rule(rbb*bd + rba*ad, rab*bd + raa*ad))) - bd = getfield(bs, 'stretch') - setfield(bs, 'stretch', round(diffmet_rule(rbb*bd, rab*bd))) - bd = getfield(bs, 'shrink') - setfield(bs, 'shrink', -round(diffmet_rule(-rbb*bd, -rab*bd))) + setfield(bs, 'width', blend_diffmet( + getfield(bs, 'width'), getfield(ga, 'kern'), db, da)) + setfield(bs, 'stretch', blend_diffmet( + getfield(bs, 'stretch'), 0, db, da)) + setfield(bs, 'shrink', -blend_diffmet( + -getfield(bs, 'shrink'), 0, db, da)) node_free(ga) return gb end end end -local function calc_ja_ja_glue() - local qm, pm = Nq.met, Np.met - if (qm.char_type==pm.char_type) and (qm.var==pm.var) then - return new_jfm_glue(qm, Nq.class, Np.class) - else - local npn, nqn = Np.nuc, Nq.nuc - local gb, db = new_jfm_glue(qm, Nq.class, - slow_find_char_class(Np.char, - qm, getchar(npn))) - local ga, da = new_jfm_glue(pm, - slow_find_char_class(Nq.char, - pm, getchar(nqn)), - Np.class) - return calc_ja_ja_aux(gb, ga, db, da); +local null_skip_table = {0, 0, 0} +-- get kanjiskip +local get_kanjiskip, kanjiskip_jfm_flag +local calc_ja_ja_glue +do + local KANJI_SKIP = luatexja.icflag_table.KANJI_SKIP + local KANJI_SKIP_JFM = luatexja.icflag_table.KANJI_SKIP_JFM + + get_kanjiskip_low = function(flag, qm, bn, bp, bh) + if flag or (qm.with_kanjiskip and (bn or bp or bh)) then + if kanjiskip_jfm_flag then + local g = node_new(id_glue); + local gx = node_new(id_glue_spec); + setfield(gx, 'stretch_order', 0); setfield(gx, 'shrink_order', 0) + local bk = qm.kanjiskip or null_skip_table + setfield(gx, 'width', bn and (bn*bk[1]) or 0) + setfield(gx, 'stretch', bp and (bp*bk[2]) or 0) + setfield(gx, 'shrink', bh and (bh*bk[3]) or 0) + setfield(g, 'spec', gx) + set_attr(g, attr_icflag, KANJI_SKIP_JFM) + return g + elseif flag then + return node_copy(kanji_skip) + else + local g = node_new(id_glue); + local gx = node_new(id_glue_spec); + setfield(gx, 'stretch_order', 0); setfield(gx, 'shrink_order', 0) + local ks = getfield(kanji_skip, 'spec') + setfield(gx, 'width', bn and (bn*getfield(ks, 'width')) or 0) + setfield(gx, 'stretch', bp and (bp*getfield(ks, 'stretch')) or 0) + setfield(gx, 'shrink', bh and (bh*getfield(ks, 'shrink')) or 0) + setfield(g, 'spec', gx) + set_attr(g, attr_icflag, KANJI_SKIP_JFM) + return g + end + end + end + + get_kanjiskip = function() + if Np.auto_kspc or Nq.auto_kspc then + local pm, qm = Np.met, Nq.met + if (pm.char_type==qm.char_type) and (qm.var==pm.var) then + return get_kanjiskip_low(true, qm, 1, 1, 1) + else + local gb = get_kanjiskip_low(true, qm, 1, 1, 1) + local ga = get_kanjiskip_low(true, pm, 1, 1, 1) + return calc_ja_ja_aux(gb, ga, 0, 1) + end + else + local g = node_copy(zero_glue) + set_attr(g, attr_icflag, kanjiskip_jfm_flag and KANJI_SKIP_JFM or KANJI_SKIP) + return g + end + end + + calc_ja_ja_glue = function () + local qm, pm = Nq.met, Np.met + local qmc, pmc = qm.char_type, pm.char_type + if (qmc==pmc) and (qm.var==pm.var) then + local g, _, kn, kp, kh = new_jfm_glue(qmc, Nq.class, Np.class) + return g, (Np.auto_kspc or Nq.auto_kspc) and get_kanjiskip_low(false, qm, kn, kp, kh) + else + local npn, nqn = Np.nuc, Nq.nuc + local gb, db, bn, bp, bh + = new_jfm_glue(qmc, Nq.class, + slow_find_char_class(Np.char, + qm, getchar(npn))) + local ga, da, an, ap, ah + = new_jfm_glue(pmc, + slow_find_char_class(Nq.char, + pm, getchar(nqn)), + Np.class) + local g = calc_ja_ja_aux(gb, ga, db, da) + local k + if (pmc==qmc) and (qm.var==pm.var) then + gb = get_kanjiskip_low(false, qm, bn, bp, bh) + ga = get_kanjiskip_low(false, pm, an, ap, ah) + k = calc_ja_ja_aux(gb, ga, db, da) + end + return g, k + end end end -------------------- 和欧文間空白量の決定 -- get xkanjiskip -local get_xkanjiskip +local get_xkanjiskip, xkanjiskip_jfm_flag local get_xkanjiskip_normal, get_xkanjiskip_jfm do local XKANJI_SKIP = luatexja.icflag_table.XKANJI_SKIP local XKANJI_SKIP_JFM = luatexja.icflag_table.XKANJI_SKIP_JFM - get_xkanjiskip_normal = function (Nn) - if (Nq.xspc>=2) and (Np.xspc%2==1) and (Nq.auto_xspc or Np.auto_xspc) then - return node_copy(xkanji_skip) - else - local g = node_copy(zero_glue) - set_attr(g, attr_icflag, XKANJI_SKIP) - return g + + get_xkanjiskip_low = function(flag, qm, bn, bp, bh) + if flag or (qm.with_kanjiskip and (bn or bp or bh)) then + if xkanjiskip_jfm_flag then + local g = node_new(id_glue); + local gx = node_new(id_glue_spec); + setfield(gx, 'stretch_order', 0); setfield(gx, 'shrink_order', 0) + local bk = qm.xkanjiskip or null_skip_table + setfield(gx, 'width', bn and bk[1] or 0) + setfield(gx, 'stretch', bp and bk[2] or 0) + setfield(gx, 'shrink', bh and bk[3] or 0) + setfield(g, 'spec', gx) + set_attr(g, attr_icflag, XKANJI_SKIP_JFM) + return g + elseif flag then + return node_copy(xkanji_skip) + else + local g = node_new(id_glue); + local gx = node_new(id_glue_spec); + setfield(gx, 'stretch_order', 0); setfield(gx, 'shrink_order', 0) + local ks = getfield(xkanji_skip, 'spec') + setfield(gx, 'width', bn and getfield(ks, 'width') or 0) + setfield(gx, 'stretch', bp and getfield(ks, 'stretch') or 0) + setfield(gx, 'shrink', bh and getfield(ks, 'shrink') or 0) + setfield(g, 'spec', gx) + set_attr(g, attr_icflag, XKANJI_SKIP_JFM) + return g + end end end - get_xkanjiskip_jfm = function (Nn) - local g + + get_xkanjiskip = function(Nn) if (Nq.xspc>=2) and (Np.xspc%2==1) and (Nq.auto_xspc or Np.auto_xspc) then - g = node_new(id_glue) - local gx = node_new(id_glue_spec); - setfield(gx, 'stretch_order', 0); setfield(gx, 'shrink_order', 0) - local bk = Nn.met.xkanjiskip or null_skip_table - setfield(gx, 'width', bk[1]) - setfield(gx, 'stretch', bk[2]) - setfield(gx, 'shrink', bk[3]) - setfield(g, 'spec', gx) + return get_xkanjiskip_low(true, Nn.met, 1, 1, 1) else - g = node_copy(zero_glue) + local g = node_copy(zero_glue) + set_attr(g, attr_icflag, xkanjiskip_jfm_flag and XKANJI_SKIP_JFM or XKANJI_SKIP) + return g end - set_attr(g, attr_icflag, XKANJI_SKIP_JFM) - return g end end -------------------- 隣接した「塊」間の処理 -local function get_OA_skip() +local function get_OA_skip(is_kanji) local pm = Np.met - return new_jfm_glue(pm, - fast_find_char_class((Nq.id == id_math and -1 or 'jcharbdd'), pm), Np.class) + local g, _, kn, kp, kh = new_jfm_glue( + pm.char_type, + fast_find_char_class((Nq.id == id_math and -1 or 'jcharbdd'), pm), + Np.class) + local k + if is_kanji==0 then + k = (Np.auto_kspc or Nq.auto_kspc) and get_kanjiskip_low(false, pm, kn, kp, kh) + elseif is_kanji==1 then + k = ((Nq.xspc>=2) and (Np.xspc%2==1) and (Nq.auto_xspc or Np.auto_xspc)) + and get_xkanjiskip_low(false, pm, kn, kp, kh) + end + return g, k end -local function get_OB_skip() +local function get_OB_skip(is_kanji) local qm = Nq.met - return new_jfm_glue(qm, Nq.class, - fast_find_char_class((Np.id == id_math and -1 or'jcharbdd'), qm)) + local g, _, kn, kp, kh = new_jfm_glue( + qm.char_type, Nq.class, + fast_find_char_class((Np.id == id_math and -1 or'jcharbdd'), qm)) + local k + if is_kanji==0 then + k = (Np.auto_kspc or Nq.auto_kspc) and get_kanjiskip_low(false, qm, kn, kp, kh) + elseif is_kanji==1 then + k = ((Nq.xspc>=2) and (Np.xspc%2==1) and (Nq.auto_xspc or Np.auto_xspc)) + and get_xkanjiskip_low(false, qm, kn, kp, kh) + end + return g, k end -- (anything) .. jachar local function handle_np_jachar(mode) local qid = Nq.id if qid==id_jglyph or ((qid==id_pbox or qid==id_pbox_w) and Nq.met) then - local g = non_ihb_flag and calc_ja_ja_glue() or get_kanjiskip() -- M->K - handle_penalty_normal(Nq.post, Np.pre, g); real_insert(g) + local g, k + if non_ihb_flag then g, k = calc_ja_ja_glue() end -- M->K + if not g then g = get_kanjiskip() end + handle_penalty_normal(Nq.post, Np.pre, g); + real_insert(g); real_insert(k) elseif Nq.met then -- qid==id_hlist - local g = non_ihb_flag and get_OA_skip() or get_kanjiskip() -- O_A->K - handle_penalty_normal(0, Np.pre, g); real_insert(g) + local g, k + if non_ihb_flag then g, k = get_OA_skip(0) end -- O_A->K + if not g then g = get_kanjiskip() end + handle_penalty_normal(0, Np.pre, g); real_insert(g); real_insert(k) elseif Nq.pre then - local g = non_ihb_flag and get_OA_skip() or get_xkanjiskip(Np) -- O_A->X - handle_penalty_normal((qid==id_hlist and 0 or Nq.post), Np.pre, g); real_insert(g) + local g, k + if non_ihb_flag then g, k = get_OA_skip(1) end -- O_A->X + if not g then g = get_xkanjiskip(Np) end + handle_penalty_normal((qid==id_hlist and 0 or Nq.post), Np.pre, g); + real_insert(g); real_insert(k) else - local g = non_ihb_flag and get_OA_skip() -- O_A + local g = non_ihb_flag and (get_OA_skip()) -- O_A if qid==id_glue then handle_penalty_normal(0, Np.pre, g) elseif qid==id_kern then handle_penalty_suppress(0, Np.pre, g) else handle_penalty_always(0, Np.pre, g) @@ -929,10 +984,10 @@ end -- jachar .. (anything) local function handle_nq_jachar() if Np.pre then - local g = non_ihb_flag and get_OB_skip() or get_xkanjiskip(Nq) -- O_B->X + local g = non_ihb_flag and get_OB_skip(1) or get_xkanjiskip(Nq) -- O_B->X handle_penalty_normal(Nq.post, (Np.id==id_hlist and 0 or Np.pre), g); real_insert(g) else - local g =non_ihb_flag and get_OB_skip() -- O_B + local g =non_ihb_flag and (get_OB_skip()) -- O_B if Np.id==id_glue then handle_penalty_normal(Nq.post, 0, g) elseif Np.id==id_kern then handle_penalty_suppress(Nq.post, 0, g) else handle_penalty_always(Nq.post, 0, g) @@ -945,7 +1000,7 @@ end local function handle_np_ja_hlist() local qid = Nq.id if qid==id_jglyph or ((qid==id_pbox or Nq.id == id_pbox_w) and Nq.met) then - local g = non_ihb_flag and get_OB_skip() or get_kanjiskip() -- O_B->K + local g = non_ihb_flag and get_OB_skip(0) or get_kanjiskip() -- O_B->K handle_penalty_normal(Nq.post, 0, g); real_insert(g) elseif Nq.met then -- Nq.id==id_hlist local g = get_kanjiskip() -- K @@ -997,13 +1052,13 @@ local function handle_list_tail(mode) -- Insert \jcharwidowpenalty Bp = widow_Bp; Np = widow_Np if Np.first then - handle_penalty_normal(0,table_current_stack[JWP] or 0) + handle_penalty_normal(0, table_current_stack[JWP] or 0) end else -- the current list is the contents of a hbox local npi, pm = Np.id, Np.met if npi == id_jglyph or (npi==id_pbox and pm) then - local g = new_jfm_glue(pm, Np.class, fast_find_char_class('boxbdd', pm)) + local g = new_jfm_glue(pm.char_type, Np.class, fast_find_char_class('boxbdd', pm)) if g then set_attr(g, attr_icflag, BOXBDD) head = insert_after(head, Np.last, g) @@ -1017,7 +1072,7 @@ local function handle_list_head(par_indented) local npi, pm = Np.id, Np.met if npi == id_jglyph or (npi==id_pbox and pm) then if non_ihb_flag then - local g = new_jfm_glue(pm, fast_find_char_class(par_indented, pm), Np.class) + local g = new_jfm_glue(pm.char_type, fast_find_char_class(par_indented, pm), Np.class) if g then set_attr(g, attr_icflag, BOXBDD) if getid(g)==id_glue and #Bp==0 then @@ -1062,14 +1117,23 @@ do local is_dir_tate = list_dir==dir_tate capsule_glyph = is_dir_tate and ltjw.capsule_glyph_tate or ltjw.capsule_glyph_yoko attr_ablshift = is_dir_tate and attr_tablshift or attr_yablshift + local TEMP = node_new(id_glue) + -- TEMP is a dummy node, which will be freed at the end of the callback. + -- ithout this node, set_attr(kanji_skip, ...) somehow creates an "orphaned" attribute list. + + do + kanji_skip = node_new(id_glue); set_attr(kanji_skip, attr_icflag, KANJI_SKIP) + local s = skip_table_to_spec(KSK) + setfield(kanji_skip, 'spec', s) + kanjiskip_jfm_flag = (getfield(s, 'width') == 1073741823) + end - setfield(kanji_skip, 'spec', skip_table_to_spec(KSK)) - get_kanjiskip = (getfield(getfield(kanji_skip, 'spec'), 'width') == 1073741823) - and get_kanjiskip_jfm or get_kanjiskip_normal - - setfield(xkanji_skip, 'spec', skip_table_to_spec(XSK)) - get_xkanjiskip = (getfield(getfield(xkanji_skip, 'spec'), 'width') == 1073741823) - and get_xkanjiskip_jfm or get_xkanjiskip_normal + do + xkanji_skip = node_new(id_glue); set_attr(xkanji_skip, attr_icflag, XKANJI_SKIP) + local s = skip_table_to_spec(XSK) + setfield(xkanji_skip, 'spec', s) + xkanjiskip_jfm_flag = (getfield(s, 'width') == 1073741823) + end if mode then -- the current list is to be line-breaked: @@ -1082,19 +1146,20 @@ do Np.width = getfield(lp, 'width') end lp=node_next(lp); lpi, lps = getid(lp), getsubtype(lp) end - return lp, node_tail(head), par_indented + return lp, node_tail(head), par_indented, TEMP else - return head, nil, 'boxbdd' + return head, nil, 'boxbdd', TEMP end end end -local tex_set_attr = tex.setattribute -local function cleanup(mode) +local ensure_tex_attr = ltjb.ensure_tex_attr +local function cleanup(mode, TEMP) -- adjust attr_icflag for avoiding error - if tex.getattribute(attr_icflag)~=0 then tex_set_attr('global', attr_icflag, 0) end - node_free(getfield(kanji_skip, 'spec')) - node_free(getfield(xkanji_skip, 'spec')) + if tex.getattribute(attr_icflag)~=0 then ensure_tex_attr(attr_icflag, 0) end + node_free(kanji_skip); + node_free(xkanji_skip); node_free(TEMP) + if mode then local h = node_next(head) if getid(h) == id_penalty and getfield(h, 'penalty') == 10000 then @@ -1112,28 +1177,28 @@ end function main(ahead, mode, dir) if not ahead then return ahead end head = ahead; - local lp, last, par_indented = init_var(mode,dir) + local lp, last, par_indented, TEMP = init_var(mode,dir) lp = calc_np(last, lp) if Np then handle_list_head(par_indented) lp = calc_np(last,lp); while Np do - adjust_nq(); - local pid, pm = Np.id, Np.met - -- 挿入部 - if pid == id_jglyph then - handle_np_jachar(mode) - elseif pm then - if pid==id_hlist then handle_np_ja_hlist() - else handle_np_jachar() end - elseif Nq.met then - if Nq.id==id_hlist then handle_nq_ja_hlist() - else handle_nq_jachar() end - end - lp = calc_np(last,lp) + adjust_nq(); + local pid, pm = Np.id, Np.met + -- 挿入部 + if pid == id_jglyph then + handle_np_jachar(mode) + elseif pm then + if pid==id_hlist then handle_np_ja_hlist() + else handle_np_jachar() end + elseif Nq.met then + if Nq.id==id_hlist then handle_nq_ja_hlist() + else handle_nq_jachar() end + end + lp = calc_np(last,lp) end handle_list_tail(mode) end - return cleanup(mode) + return cleanup(mode, TEMP) end end