--
luatexbase.provides_module({
name = 'luatexja.jfmglue',
- date = '2014/1/21',
+ date = '2014/02/02',
description = 'Insertion process of JFM glues and kanjiskip',
})
module('luatexja.jfmglue', package.seeall)
luatexja.load_module('stack'); local ltjs = luatexja.stack
luatexja.load_module('jfont'); local ltjf = luatexja.jfont
+luatexja.load_module('direction'); local ltjd = luatexja.direction
local pairs = pairs
local Dnode = node.direct or node
local set_attr = Dnode.set_attribute
local insert_before = Dnode.insert_before
local insert_after = Dnode.insert_after
-local node_next = Dnode.getnext
+local node_next = (Dnode ~= node) and Dnode.getnext or node.next
local round = tex.round
+local ltjd_make_dir_node = ltjd.make_dir_node
local ltjf_font_metric_table = ltjf.font_metric_table
local ltjf_find_char_class = ltjf.find_char_class
local node_new = Dnode.new
local node_copy = Dnode.copy
-local node_remove = Dnode.remove
+local node_remove = luatexja.Dnode_remove -- Dnode.remove
local node_tail = Dnode.tail
local node_free = Dnode.free
local node_end_of_math = Dnode.end_of_math
+local dir_tate = 3
+local dir_yoko = 4
local id_glyph = node.id('glyph')
local id_hlist = node.id('hlist')
local PACKED = luatexja.icflag_table.PACKED
local KINSOKU = luatexja.icflag_table.KINSOKU
local FROM_JFM = luatexja.icflag_table.FROM_JFM
-local KANJI_SKIP = luatexja.icflag_table.KANJI_SKIP
-local XKANJI_SKIP = luatexja.icflag_table.XKANJI_SKIP
local PROCESSED = luatexja.icflag_table.PROCESSED
local IC_PROCESSED = luatexja.icflag_table.IC_PROCESSED
local BOXBDD = luatexja.icflag_table.BOXBDD
local kanji_skip
local xkanji_skip
local table_current_stack
+local list_dir
local attr_curjfnt = luatexbase.attributes['ltj@curjfnt']
+local attr_dir = luatexbase.attributes['ltj@dir']
local attr_icflag = luatexbase.attributes['ltj@icflag']
local function get_attr_icflag(p)
-------------------- Helper functions
-local function copy_attr(new, old)
+local function copy_attr(new, old)
-- 仕様が決まるまで off にしておく
end
setfield(zero_glue, 'spec', spec_zero_glue)
local function skip_table_to_spec(n)
- local g, st = node_new(id_glue_spec), ltjs.fast_get_skip_table(n)
+ local g, st = node_new(id_glue_spec), ltjs.fast_get_stack_skip(n)
setfield(g, 'width', st.width)
setfield(g, 'stretch', st.stretch)
setfield(g, 'shrink', st.shrink)
-------------------- hlist 内の文字の検索
local first_char, last_char, find_first_char
-
+do
+local ltjd_glyph_from_packed = ltjd.glyph_from_packed
local function check_box(box_ptr, box_end)
local p = box_ptr; local found_visible_node = false
- if not p then
+ if not p then
find_first_char = false; last_char = nil
return true
end
p = node_next(node_next(node_next(p))); pid = getid(p) -- p must be glyph_node
end
if pid==id_glyph then
- repeat
- if find_first_char then
+ repeat
+ if find_first_char then
first_char = p; find_first_char = false
end
last_char = p; found_visible_node = true; p=node_next(p)
- if (not p) or p==box_end then
- return found_visible_node
+ if (not p) or p==box_end then
+ return found_visible_node
end
until getid(p)~=id_glyph
pid = getid(p) -- p must be non-nil
end
if pid==id_kern then
- if get_attr_icflag(p)==IC_PROCESSED then
+ local pa = get_attr_icflag(p)
+ --if pa==IC_PROCESSED or pa == PACKED then
+ if pa==IC_PROCESSED then
-- do nothing
elseif getsubtype(p)==2 then
- p = node_next(node_next(p));
+ p = node_next(node_next(p));
-- Note that another node_next will be executed outside this if-statement.
else
found_visible_node = true
- if find_first_char then
- find_first_char = false
- else
- last_char = nil
- end
+ find_first_char = false; last_char = nil
end
elseif pid==id_hlist then
if PACKED == get_attr_icflag(p) then
+ local s = ltjd_glyph_from_packed(p)
if find_first_char then
- first_char = getlist(p); find_first_char = false
+ first_char = s; find_first_char = false
end
- last_char = getlist(p); found_visible_node = true
+ last_char = s; found_visible_node = true
else
if getfield(p, 'shift')==0 then
if check_box(getlist(p), nil) then found_visible_node = true end
- else if find_first_char then
- find_first_char = false
- else
- last_char = nil
- end
+ else
+ find_first_char = false; last_char = nil
end
end
elseif pid==id_math then
- if find_first_char then
+ if find_first_char then
first_char = p; find_first_char = false
end
last_char = p; found_visible_node = true
+ --elseif pid==id_rule and get_attr_icflag(p)==PACKED then -- do nothing
elseif not (pid==id_ins or pid==id_mark
or pid==id_adjust or pid==id_whatsit
or pid==id_penalty) then
found_visible_node = true
- if find_first_char then
- find_first_char = false
- else
- last_char = nil
- end
+ find_first_char = false; last_char = nil
end
p = node_next(p)
end
return found_visible_node
-end
+end
function check_box_high(Nx, box_ptr, box_end)
first_char = nil; last_char = nil; find_first_char = true
local first_char = first_char
if first_char then
if getid(first_char)==id_glyph then
- if getfont(first_char) == (has_attr(first_char, attr_curjfnt) or -1) then
+ if getfont(first_char) == (has_attr(first_char, attr_curjfnt) or -1) then
set_np_xspc_jachar(Nx, first_char)
else
set_np_xspc_alchar(Nx, getchar(first_char),first_char, 1)
end
return last_char
end
-
+end
-------------------- Np の計算と情報取得
-luatexbase.create_callback("luatexja.jfmglue.whatsit_getinfo", "data",
- function (Np, lp, Nq)
- if Np.nuc then return Np
- else
+luatexbase.create_callback("luatexja.jfmglue.whatsit_getinfo", "data",
+ function (Np, lp, Nq)
+ if Np.nuc then return Np
+ else
return Np -- your code
end
end)
-luatexbase.create_callback("luatexja.jfmglue.whatsit_after", "data",
+luatexbase.create_callback("luatexja.jfmglue.whatsit_after", "data",
function (stat, Nq, Np) return false end)
-- calc next Np
do
local function set_attr_icflag_processed(p)
- if get_attr_icflag(p)<= ITALIC then
- set_attr(p, attr_icflag, PROCESSED)
+ if get_attr_icflag(p)<= ITALIC then
+ set_attr(p, attr_icflag, PROCESSED)
end
end
local function check_next_ickern(lp)
- if getid(lp) == id_kern and ITALIC == get_attr_icflag(lp) then
+ if lp and getid(lp) == id_kern and ITALIC == get_attr_icflag(lp) then
set_attr(lp, attr_icflag, IC_PROCESSED)
Np.last = lp; return node_next(lp)
- else
+ else
Np.last = Np.nuc; return lp
end
end
local function calc_np_pbox(lp, last)
Np.first = Np.first or lp; Np.id = id_pbox
- local lpa = KINSOKU -- dummy=
+ local lpa, nc = KINSOKU, nil
set_attr(lp, attr_icflag, get_attr_icflag(lp));
- while lp~=last and lpa>=PACKED and lpa<BOXBDD do
- Np.nuc = lp;
- lp = node_next(lp); lpa = has_attr(lp, attr_icflag) or 0
- -- get_attr_icflag() ではいけない!
+ while lp ~=last and (lpa>=PACKED) and (lpa<BOXBDD) do
+ nc, lp = lp, node_next(lp); lpa = lp and has_attr(lp, attr_icflag) or 0
+ -- get_attr_icflag() ではいけない!
end
+ Np.nuc = nc
return check_next_ickern(lp)
end
local calc_np_auxtable = {
[id_glyph] = function (lp)
Np.first, Np.nuc = (Np.first or lp), lp;
- Np.id = (getfont(lp) == (has_attr(lp, attr_curjfnt) or -1))
+ Np.id = (getfont(lp) == (has_attr(lp, attr_curjfnt) or -1))
and id_jglyph or id_glyph
- return true, check_next_ickern(node_next(lp));
+ return true, check_next_ickern(node_next(lp));
end,
- [id_hlist] = function(lp)
- Np.first = Np.first or lp; Np.last = lp; Np.nuc = lp;
- set_attr(lp, attr_icflag, PROCESSED)
- Np.id = (getfield(lp, 'shift')~=0) and id_box_like or id_hlist
- return true, node_next(lp)
+ [id_hlist] = function(lp)
+ local op, flag
+ head, lp, op, flag = ltjd_make_dir_node(head, lp, list_dir, 'jfm hlist')
+ Np.first = Np.first or op; Np.last = op; Np.nuc = op;
+ Np.id = (flag or getfield(op, 'shift')~=0) and id_box_like or id_hlist
+ return true, lp
+ end,
+ [id_vlist] = function(lp)
+ local op
+ head, lp, op = ltjd_make_dir_node(head, lp, list_dir, 'jfm:' .. getid(lp))
+ Np.first = Np.first or op; Np.last = op; Np.nuc = op;
+ Np.id = id_box_like;
+ return true, lp
end,
box_like = function(lp)
- Np.first = Np.first or lp; Np.nuc = lp; Np.last = lp;
- Np.id = id_box_like; set_attr(lp, attr_icflag, PROCESSED)
- return true, node_next(lp);
+ Np.first = Np.first or lp; Np.last = lp; Np.nuc = lp;
+ Np.id = id_box_like;
+ return true, node_next(lp)
end,
- skip = function(lp)
+ skip = function(lp)
set_attr(lp, attr_icflag, PROCESSED)
return false, node_next(lp)
end,
- [id_whatsit] = function(lp)
+ [id_whatsit] = function(lp)
local lps = getsubtype(lp)
if lps==sid_user then
- if getsubtype(lp, 'user_id')==luatexja.userid_table.IHB then
- local lq = node_next(lp);
+ if getfield(lp, 'user_id')==luatexja.userid_table.IHB then
+ local lq = node_next(lp);
head = node_remove(head, lp); node_free(lp); ihb_flag = true
return false, lq;
else
set_attr(lp, attr_icflag, PROCESSED)
luatexbase.call_callback("luatexja.jfmglue.whatsit_getinfo",
Np, lp, Nq)
- if Np.nuc then
- Np.id = id_pbox_w; Np.first = Np.nuc; Np.last = Np.nuc;
+ if Np.nuc then
+ Np.id = id_pbox_w; Np.first = Np.nuc; Np.last = Np.nuc;
return true, node_next(lp)
else
return false, node_next(lp)
else
-- we do special treatment for these whatsit nodes.
if lps == sid_start_link or lps == sid_start_thread then
- Np.first = lp
+ Np.first = lp
elseif lps == sid_end_link or lps == sid_end_thread then
Np.first, Nq.last = nil, lp;
end
end
end,
[id_math] = function(lp)
- Np.first, Np.nuc = (Np.first or lp), lp;
+ Np.first, Np.nuc = (Np.first or lp), lp;
set_attr(lp, attr_icflag, PROCESSED)
- lp = node_end_of_math(lp)
+ lp = node_end_of_math(lp)
set_attr(lp, attr_icflag, PROCESSED)
Np.last, Np.id = lp, id_math;
- return true, node_next(lp);
+ return true, node_next(lp);
end,
discglue = function(lp)
- Np.first, Np.nuc, Np.last = (Np.first or lp), lp, lp;
+ Np.first, Np.nuc, Np.last = (Np.first or lp), lp, lp;
Np.id = getid(lp); set_attr(lp, attr_icflag, PROCESSED)
return true, node_next(lp)
end,
- [id_kern] = function(lp)
+ [id_kern] = function(lp)
Np.first = Np.first or lp
if getsubtype(lp)==2 then
set_attr(lp, attr_icflag, PROCESSED); lp = node_next(lp)
set_attr(lp, attr_icflag, PROCESSED); lp = node_next(lp)
set_attr(lp, attr_icflag, PROCESSED); Np.nuc = lp
Np.id = (getfont(lp) == (has_attr(lp, attr_curjfnt) or -1)) and id_jglyph or id_glyph
- return true, check_next_ickern(node_next(lp));
+ return true, check_next_ickern(node_next(lp));
else
Np.id = id_kern; set_attr(lp, attr_icflag, PROCESSED)
Np.last = lp; return true, node_next(lp)
return false, node_next(lp)
end,
}
-calc_np_auxtable[id_vlist] = calc_np_auxtable.box_like
calc_np_auxtable[id_rule] = calc_np_auxtable.box_like
calc_np_auxtable[13] = calc_np_auxtable.box_like
calc_np_auxtable[id_ins] = calc_np_auxtable.skip
for k in pairs(Np) do Np[k] = nil end
for k = 1,#Bp do Bp[k] = nil end
- while lp ~= last do
+ while lp ~= last do
local lpa = has_attr(lp, attr_icflag) or 0
-- unbox 由来ノードの検出
if lpa>=PACKED then
if lpa%PROCESSED_BEGIN_FLAG == BOXBDD then
- local lq = node_next(lp)
+ local lq = node_next(lp)
head = node_remove(head, lp); node_free(lp); lp = lq
else return calc_np_pbox(lp, last)
end -- id_pbox
-- We think that "Np is a Japanese character" if Np.met~=nil,
-- "Np is an alphabetic character" if Np.pre~=nil,
-- "Np is not a character" otherwise.
-local after_hlist, after_alchar, extract_np
+after_hlist = nil -- global
+local after_alchar, extract_np
do
local PRE = luatexja.stack_table_index.PRE
local POST = luatexja.stack_table_index.POST
local attr_autoxspc = luatexbase.attributes['ltj@autoxspc']
function set_np_xspc_jachar(Nx, x)
local m = ltjf_font_metric_table[getfont(x)]
- local cls, c = slow_find_char_class(has_attr(x, attr_orig_char), m, getchar(x))
- Nx.met, Nx.char = m, c; Nx.class = cls;
+ local cls, c
+ if list_dir == dir_tate then
+ local c1, c2 = getchar(x), has_attr(x, attr_orig_char)
+ c = has_attr(x, attr_dir) or c1 or c2
+ cls = ltjf_find_char_class(c, m)
+ if cls==0 then cls = slow_find_char_class(c2, m, c1) end
+ else
+ cls, c = slow_find_char_class(has_attr(x, attr_orig_char), m, getchar(x))
+ end
+ Nx.met, Nx.char = m, c; Nx.class = cls;
if cls~=0 then set_attr(x, attr_jchar_class, cls) end
Nx.pre = table_current_stack[PRE + c] or 0
Nx.post = table_current_stack[POST + c] or 0
Nx.xspc = table_current_stack[XSP + c] or 3
Nx.kcat = table_current_stack[KCAT + c] or 0
Nx.auto_kspc, Nx.auto_xspc = (has_attr(x, attr_autospc)==1), (has_attr(x, attr_autoxspc)==1)
- end
+ end
local set_np_xspc_jachar = set_np_xspc_jachar
-- 欧文文字のデータを取得
elseif i == id_math then return set_np_xspc_alchar(Np, -1, x)
end
end
-
+
-- change the information for the next loop
-- (will be done if Nx is an alphabetic character or a hlist)
after_hlist = function (Nx)
local s = Nx.last_char
if s then
if getid(s)==id_glyph then
- if getfont(s) == (has_attr(s, attr_curjfnt) or -1) then
+ if getfont(s) == (has_attr(s, attr_curjfnt) or -1) then
set_np_xspc_jachar(Nx, s)
else
set_np_xspc_alchar(Nx, getchar(s), s, 2)
Nx.pre, Nx.met = nil, nil
end
end
-
+
after_alchar = function (Nx)
local x = Nx.nuc
return set_np_xspc_alchar(Nx, getchar(x), x, 2)
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;
+ Bp[1]=p;
set_attr(p, attr_icflag, KINSOKU)
end
else for _, v in pairs(Bp) do add_penalty(v,a) end
local n
if g then
n,d = node_copy(g[2]), g[3]
- if g[1] then
+ if g[1] then
local f = node_new(id_glue)
set_attr(f, attr_icflag, g[4])
setfield(f, 'spec', n)
-- get kanjiskip
local get_kanjiskip
-
-local function get_kanjiskip_normal()
- 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
+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
-end
-local function get_kanjiskip_jfm()
- 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 {0, 0, 0}
- 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])
+ 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 {0, 0, 0}
+ 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 {0, 0, 0}
+ 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
- local ak = pm.kanjiskip or {0, 0, 0}
- 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])))
+ g = node_copy(zero_glue)
end
- setfield(g, 'spec', gx)
- else
- g = node_copy(zero_glue)
+ set_attr(g, attr_icflag, KANJI_SKIP_JFM)
+ return g
end
- set_attr(g, attr_icflag, KANJI_SKIP)
- return g
end
local calc_ja_ja_aux
calc_ja_ja_aux = function (gb,ga, db, da)
local rbb, rab = (1-db)/2, (1-da)/2 -- 「前の文字」由来のグルーの割合
local rba, raa = (1+db)/2, (1+da)/2 -- 「前の文字」由来のグルーの割合
- if diffmet_rule ~= math.two_pleft and diffmet_rule ~= math.two_pright
+ 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
end
- if not gb then
- if ga then
- gb = node_new(id_kern); setfield(gb, 'kern', 0)
+ if not gb then
+ if ga then
+ gb = node_new(id_kern); setfield(gb, 'kern', 0)
else return nil end
- elseif not ga then
+ elseif not ga then
ga = node_new(id_kern); setfield(ga, 'kern', 0)
end
-
+
local k = 2*getid(gb) - getid(ga)
if k == bg_ag then
local bs, as = getfield(gb, 'spec'), getfield(ga, 'spec')
setfield(gb, 'kern', round(diffmet_rule(rbb*bd + rba*ad, rab*bd + raa*ad)))
node_free(ga)
return gb
- elseif k == bk_ag then
+ elseif k == bk_ag then
local as = getfield(ga, 'spec')
-- gb: kern, ga: glue
local bd, ad = getfield(gb, 'kern'), getfield(as, 'width')
local gb, db = new_jfm_glue(qm, Nq.class,
slow_find_char_class(has_attr(npn, attr_orig_char),
qm, getchar(npn)))
- local ga, da = new_jfm_glue(pm,
+ local ga, da = new_jfm_glue(pm,
slow_find_char_class(has_attr(nqn, attr_orig_char),
pm, getchar(nqn)),
Np.class)
- return calc_ja_ja_aux(gb, ga, db, da);
+ return calc_ja_ja_aux(gb, ga, db, da);
end
end
end
-- get xkanjiskip
local get_xkanjiskip
-local function get_xkanjiskip_normal(Nn)
- if (Nq.xspc>=2) and (Np.xspc%2==1) and (Nq.auto_xspc or Np.auto_xspc) then
- local f = node_copy(xkanji_skip)
- return f
- else
- local g = node_copy(zero_glue)
- set_attr(g, attr_icflag, XKANJI_SKIP)
- return g
+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
+ local f = node_copy(xkanji_skip)
+ return f
+ else
+ local g = node_copy(zero_glue)
+ set_attr(g, attr_icflag, XKANJI_SKIP)
+ return g
+ end
end
-end
-local function get_xkanjiskip_jfm(Nn)
- local g
- 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 {0, 0, 0}
- setfield(gx, 'width', bk[1])
- setfield(gx, 'stretch', bk[2])
- setfield(gx, 'shrink', bk[3])
- setfield(g, 'spec', gx)
- else
- g = node_copy(zero_glue)
+ get_xkanjiskip_jfm = function (Nn)
+ local g
+ 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 {0, 0, 0}
+ setfield(gx, 'width', bk[1])
+ setfield(gx, 'stretch', bk[2])
+ setfield(gx, 'shrink', bk[3])
+ setfield(g, 'spec', gx)
+ else
+ g = node_copy(zero_glue)
+ end
+ set_attr(g, attr_icflag, XKANJI_SKIP_JFM)
+ return g
end
- set_attr(g, attr_icflag, XKANJI_SKIP)
- return g
end
-------------------- 隣接した「塊」間の処理
local function get_OA_skip()
if not ihb_flag then
local pm = Np.met
- return new_jfm_glue(pm,
+ return new_jfm_glue(pm,
fast_find_char_class(((Nq.id == id_math and -1) or (type(Nq.char)=='string' and Nq.char or 'jcharbdd')), pm), Np.class)
else return nil
end
local function get_OB_skip()
if not ihb_flag then
local qm = Nq.met
- return new_jfm_glue(qm, Nq.class,
+ return new_jfm_glue(qm, Nq.class,
fast_find_char_class(((Np.id == id_math and -1) or'jcharbdd'), qm))
else return nil
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
+ if qid==id_jglyph or ((qid==id_pbox or qid==id_pbox_w) and Nq.met) then
local g = calc_ja_ja_glue() or get_kanjiskip() -- M->K
handle_penalty_normal(Nq.post, Np.pre, g); real_insert(g)
elseif Nq.met then -- qid==id_hlist
local g = get_OA_skip() or get_kanjiskip() -- O_A->K
handle_penalty_normal(0, Np.pre, g); real_insert(g)
- elseif Nq.pre then
+ elseif Nq.pre then
local g = 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)
else
-- jachar .. (anything)
local function handle_nq_jachar()
- if Np.pre then
+ if Np.pre then
local g = get_OB_skip() 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
-- (anything) .. (和文文字で始まる hlist)
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
+ if qid==id_jglyph or ((qid==id_pbox or Nq.id == id_pbox_w) and Nq.met) then
local g = get_OB_skip() 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
handle_penalty_suppress(0, 0, g); real_insert(g)
- elseif Nq.pre then
+ elseif Nq.pre then
local g = get_xkanjiskip(Np) -- X
handle_penalty_suppress(0, 0, g); real_insert(g)
end
-- (和文文字で終わる hlist) .. (anything)
local function handle_nq_ja_hlist()
- if Np.pre then
+ if Np.pre then
local g = get_xkanjiskip(Nq) -- X
handle_penalty_suppress(0, 0, g); real_insert(g)
end
-- Nq が前側のクラスタとなることによる修正
do
local adjust_nq_aux = {
- [id_glyph] = function()
+ [id_glyph] = function()
local x = Nq.nuc
return set_np_xspc_alchar(Nq, getchar(x),x, 2)
end, -- after_alchar(Nq)
[id_hlist] = function() after_hlist(Nq) end,
[id_pbox] = function() after_hlist(Nq) end,
[id_disc] = function() after_hlist(Nq) end,
- [id_pbox_w] = function()
+ [id_pbox_w] = function()
luatexbase.call_callback("luatexja.jfmglue.whatsit_after",
- false, Nq, Np)
+ false, Nq, Np)
end,
}
-------------------- 開始・終了時の処理
+do
-- リスト末尾の処理
local JWP = luatexja.stack_table_index.JWP
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
+ 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))
if g then
set_attr(g, attr_icflag, BOXBDD)
-- リスト先頭の処理
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 npi == id_jglyph or (npi==id_pbox and pm) then
if not ihb_flag then
local g = new_jfm_glue(pm, fast_find_char_class(par_indented, pm), Np.class)
if g then
-- initialize
-- return value: (the initial cursor lp), (last node)
-local function init_var(mode)
- -- 1073741823: max_dimen
- Bp, widow_Bp, widow_Np = {}, {}, {first = nil}
- table_current_stack = ltjs.table_current_stack
-
- kanji_skip = node_new(id_glue)
- setfield(kanji_skip, 'spec', skip_table_to_spec('kanjiskip'))
- set_attr(kanji_skip, attr_icflag, KANJI_SKIP)
- get_kanjiskip = (getfield(getfield(kanji_skip, 'spec'), 'width') == 1073741823)
- and get_kanjiskip_jfm or get_kanjiskip_normal
-
- xkanji_skip = node_new(id_glue)
- setfield(xkanji_skip, 'spec', skip_table_to_spec('xkanjiskip'))
- set_attr(xkanji_skip, attr_icflag, XKANJI_SKIP)
- get_xkanjiskip = (getfield(getfield(xkanji_skip, 'spec'), 'width') == 1073741823)
- and get_xkanjiskip_jfm or get_xkanjiskip_normal
-
- Np = {
- auto_kspc=nil, auto_xspc=nil, char=nil, class=nil,
- first=nil, id=nil, last=nil, met=nil, nuc=nil,
- post=nil, pre=nil, xspc=nil,
- }
- Nq = {
- auto_kspc=nil, auto_xspc=nil, char=nil, class=nil,
- first=nil, id=nil, last=nil, met=nil, nuc=nil,
- post=nil, pre=nil, xspc=nil,
- }
- if mode then
- -- the current list is to be line-breaked:
- -- hbox from \parindent is skipped.
- local lp, par_indented, lpi, lps = head, 'boxbdd', getid(head), getsubtype(head)
- while lp and ((lpi==id_whatsit and lps~=sid_user)
- or ((lpi==id_hlist) and (lps==3))) do
- if (lpi==id_hlist) and (lps==3) then par_indented = 'parbdd' end
- lp=node_next(lp); lpi, lps = getid(lp), getsubtype(lp) end
- return lp, node_tail(head), par_indented
- else
- -- the current list is the contents of a hbox:
- -- insert a sentinel
- local g = node_new(id_kern)
- insert_after(head, node_tail(head), g); last = g
- return head, g, 'boxbdd'
+local init_var
+do
+ local KANJI_SKIP = luatexja.icflag_table.KANJI_SKIP
+ local XKANJI_SKIP = luatexja.icflag_table.XKANJI_SKIP
+ local KSK = luatexja.stack_table_index.KSK
+ local XSK = luatexja.stack_table_index.XSK
+ local DIR = luatexja.stack_table_index.DIR
+ init_var = function (mode)
+ -- 1073741823: max_dimen
+ Bp, widow_Bp, widow_Np = {}, {}, {first = nil}
+ table_current_stack = ltjs.table_current_stack
+
+ list_dir = table_current_stack[DIR] or dir_yoko
+ kanji_skip = node_new(id_glue)
+ setfield(kanji_skip, 'spec', skip_table_to_spec(KSK))
+ set_attr(kanji_skip, attr_icflag, KANJI_SKIP)
+ get_kanjiskip = (getfield(getfield(kanji_skip, 'spec'), 'width') == 1073741823)
+ and get_kanjiskip_jfm or get_kanjiskip_normal
+
+ xkanji_skip = node_new(id_glue)
+ setfield(xkanji_skip, 'spec', skip_table_to_spec(XSK))
+ set_attr(xkanji_skip, attr_icflag, XKANJI_SKIP)
+ get_xkanjiskip = (getfield(getfield(xkanji_skip, 'spec'), 'width') == 1073741823)
+ and get_xkanjiskip_jfm or get_xkanjiskip_normal
+
+ Np = {
+ auto_kspc=nil, auto_xspc=nil, char=nil, class=nil,
+ first=nil, id=nil, last=nil, met=nil, nuc=nil,
+ post=nil, pre=nil, xspc=nil,
+ }
+ Nq = {
+ auto_kspc=nil, auto_xspc=nil, char=nil, class=nil,
+ first=nil, id=nil, last=nil, met=nil, nuc=nil,
+ post=nil, pre=nil, xspc=nil,
+ }
+ if mode then
+ -- the current list is to be line-breaked:
+ -- hbox from \parindent is skipped.
+ local lp, par_indented, lpi, lps = head, 'boxbdd', getid(head), getsubtype(head)
+ while lp and ((lpi==id_whatsit and lps~=sid_user)
+ or ((lpi==id_hlist) and (lps==3))) do
+ if (lpi==id_hlist) and (lps==3) then
+ Np.char, par_indented = 'parbdd', 'parbdd'
+ Np.width = getfield(lp, 'width')
+ end
+ lp=node_next(lp); lpi, lps = getid(lp), getsubtype(lp) end
+ return lp, node_tail(head), par_indented
+ else
+ return head, nil, 'boxbdd'
+ end
end
end
-local function cleanup(mode, last)
+local function cleanup(mode)
-- adjust attr_icflag for avoiding error
tex.setattribute('global', attr_icflag, 0)
node_free(kanji_skip); node_free(xkanji_skip)
end
return head
else
- head = node_remove(head, last); node_free(last);-- remove the sentinel
- set_attr(head, attr_icflag,
+ set_attr(head, attr_icflag,
get_attr_icflag(head) + PROCESSED_BEGIN_FLAG);
return head
end
function main(ahead, mode)
if not ahead then return ahead end
head = ahead;
- local lp, last, par_indented = init_var(mode);
+ local lp, last, par_indented = init_var(mode)
lp = calc_np(lp, last)
- if Np then
+ if Np then
extract_np(); handle_list_head(par_indented)
else
- return cleanup(mode, last)
+ return cleanup(mode)
end
lp = calc_np(lp, last)
while Np do
extract_np();
- adjust_nq();
+ adjust_nq();
local pid, pm = Np.id, Np.met
-- 挿入部
- if pid == id_jglyph then
+ if pid == id_jglyph then
handle_np_jachar(mode)
- elseif pm then
+ elseif pm then
if pid==id_hlist then handle_np_ja_hlist()
else handle_np_jachar() end
- elseif Nq.met then
+ elseif Nq.met then
if Nq.id==id_hlist then handle_nq_ja_hlist()
else handle_nq_jachar() end
end
lp = calc_np(lp, last)
end
handle_list_tail(mode)
- return cleanup(mode, last)
+ return cleanup(mode)
+end
end
do
local IHB = luatexja.userid_table.IHB
local BPAR = luatexja.userid_table.BPAR
- local node_prev = Dnode.getprev
+ local node_prev = (Dnode ~= node) and Dnode.getprev or node.prev
local node_write = Dnode.write
-- \inhibitglue
end
local function whatsit_callback(Np, lp, Nq)
- if Np and Np.nuc then return Np
+ if Np and Np.nuc then return Np
elseif Np and getfield(lp, 'user_id') == BPAR then
Np.first = lp; Np.nuc = lp; Np.last = lp
Np.char = 'parbdd'