--
luatexbase.provides_module({
name = 'luatexja.jfmglue',
- date = '2014/1/12',
+ date = '2014/1/21',
description = 'Insertion process of JFM glues and kanjiskip',
})
module('luatexja.jfmglue', package.seeall)
luatexja.load_module('jfont'); local ltjf = luatexja.jfont
luatexja.load_module('pretreat'); local ltjp = luatexja.pretreat
-local has_attr = node.has_attribute
-local set_attr = node.set_attribute
-local insert_before = node.insert_before
-local node_next = node.next
+local Dnode = node -- node.direct or node
+
+local setfield = (Dnode == node.direct) and Dnode.setfield or function(n, i, c) n[i] = c end
+local getfield = (Dnode == node.direct) and Dnode.getfield or function(n, i) return n[i] end
+local getid = (Dnode == node.direct) and Dnode.getid or function(n) return n.id end
+local getfont = (Dnode == node.direct) and Dnode.getfont or function(n) return n.font end
+local getlist = (Dnode == node.direct) and Dnode.getlist or function(n) return n.head end
+local getchar = (Dnode == node.direct) and Dnode.getlist or function(n) return n.char end
+local getsubtype = (Dnode == node.direct) and Dnode.getlist or function(n) return n.subtype end
+
+local has_attr = Dnode.has_attribute
+local set_attr = Dnode.set_attribute
+local insert_before = Dnode.insert_before
+local insert_after = Dnode.insert_after
+local node_next = Dnode.next
local round = tex.round
local ltjf_font_metric_table = ltjf.font_metric_table
local ltjf_find_char_class = ltjf.find_char_class
-local node_new = node.new
-local node_copy = node.copy
+local node_new = Dnode.new
+local node_copy = Dnode.copy
+local node_remove = Dnode.remove
+local node_tail = Dnode.tail
+local node_free = Dnode.free
+local node_end_of_math = Dnode.end_of_math
+
local id_glyph = node.id('glyph')
local id_hlist = node.id('hlist')
if lp.subtype==sid_user then
if lp.user_id==luatexja.userid_table.IHB then
local lq = node_next(lp);
- head = node.remove(head, lp); node.free(lp); ihb_flag = true
+ head = node_remove(head, lp); node_free(lp); ihb_flag = true
return false, lq;
else
set_attr(lp, attr_icflag, PROCESSED)
[id_math] = function(lp)
Np.first, Np.nuc = (Np.first or lp), lp;
set_attr(lp, attr_icflag, PROCESSED) -- set_attr_icflag_processed(lp);
- lp = node.end_of_math(lp)
+ lp = node_end_of_math(lp)
set_attr(lp, attr_icflag, PROCESSED) -- set_attr_icflag_processed(lp);
Np.last, Np.id = lp, id_math;
return true, node_next(lp);
if lpa>=PACKED then
if lpa%PROCESSED_BEGIN_FLAG == BOXBDD then
local lq = node_next(lp)
- head = node.remove(head, lp); node.free(lp); lp = lq
+ head = node_remove(head, lp); node_free(lp); lp = lq
else return calc_np_pbox(lp, last)
end -- id_pbox
else
c = x.char
else
while xc and xs and xs%4>=2 do
- x = node.tail(xc); xc, xs = x.components, x.subtype
+ x = node_tail(xc); xc, xs = x.components, x.subtype
end
c = x.char
end
gb.spec.shrink = -round(diffmet_rule(
-rbb*gb.spec.shrink - rba*ga.spec.shrink,
-rab*gb.spec.shrink - raa*ga.spec.shrink ))
- node.free(ga)
+ node_free(ga)
return gb
elseif k == 'kernkern' then
-- 両方とも kern.
gb.kern = round(diffmet_rule(
rbb*gb.kern + rba*ga.kern,
rab*gb.kern + raa*ga.kern ))
- node.free(ga)
+ node_free(ga)
return gb
elseif k == 'kernglue' then
-- gb: kern, ga: glue
rba*ga.spec.stretch, raa*ga.spec.stretch ))
ga.spec.shrink = -round(diffmet_rule(
-rba*ga.spec.shrink,-raa*ga.spec.shrink ))
- node.free(gb)
+ node_free(gb)
return ga
else
-- gb: glue, ga: kern
rbb*gb.spec.stretch, rab*gb.spec.stretch ))
gb.spec.shrink = -round(diffmet_rule(
-rbb*gb.spec.shrink,-rab*gb.spec.shrink ))
- node.free(ga)
+ node_free(ga)
return gb
end
end
local g = new_jfm_glue(pm, Np.class, fast_find_char_class('boxbdd', pm))
if g then
set_attr(g, attr_icflag, BOXBDD)
- head = node.insert_after(head, Np.last, g)
+ head = insert_after(head, Np.last, g)
end
end
end
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 = lp.id, lp.subtype end
- return lp, node.tail(head), par_indented
+ 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)
- node.insert_after(head, node.tail(head), g); last = g
+ insert_after(head, node_tail(head), g); last = g
return head, g, 'boxbdd'
end
end
local function cleanup(mode, last)
-- adjust attr_icflag for avoiding error
tex.setattribute('global', attr_icflag, 0)
- node.free(kanji_skip); node.free(xkanji_skip)
+ node_free(kanji_skip); node_free(xkanji_skip)
if mode then
local h = node_next(head)
if h.id == id_penalty and h.penalty == 10000 then
end
return head
else
- head = node.remove(head, last); node.free(last);-- remove the sentinel
+ head = node_remove(head, last); node_free(last);-- remove the sentinel
set_attr(head, attr_icflag,
get_attr_icflag(head) + PROCESSED_BEGIN_FLAG);
return head
end
end
+ local node_prev = Dnode.prev
local function whatsit_after_callback(s, Nq, Np)
if not s and Nq.nuc.user_id == BPAR then
- local x, y = node.prev(Nq.nuc), Nq.nuc
+ local x, y = node_prev(Nq.nuc), Nq.nuc
Nq.first, Nq.nuc, Nq.last = x, x, x
- head = node.remove(head, y)
+ head = node_remove(head, y)
end
return s
end
luatexja.load_module('stack'); local ltjs = luatexja.stack
luatexja.load_module('setwidth'); local ltjw = luatexja.setwidth
-local node_new = node.new
-local node_next = node.next
-local node_free = node.free
-local has_attr = node.has_attribute
-local set_attr = node.set_attribute
+local Dnode = node.direct or node
+
+local setfield = (Dnode == node.direct) and Dnode.setfield or function(n, i, c) n[i] = c end
+local getfield = (Dnode == node.direct) and Dnode.getfield or function(n, i) return n[i] end
+local getid = (Dnode == node.direct) and Dnode.getid or function(n) return n.id end
+local getlist = (Dnode == node.direct) and Dnode.getlist or function(n) return n.head end
+local getchar = (Dnode == node.direct) and Dnode.getlist or function(n) return n.char end
+
+local nullfunc = function(n) return n end
+local to_node = (Dnode == node.direct) and Dnode.tonode or nullfunc
+local to_direct = (Dnode == node.direct) and Dnode.todirect or nullfunc
+
+local node_traverse = Dnode.traverse
+local node_new = Dnode.new
+local node_next = Dnode.next
+local node_free = Dnode.free
+local has_attr = Dnode.has_attribute
+local set_attr = Dnode.set_attribute
local tex_getcount = tex.getcount
local attr_jchar_class = luatexbase.attributes['ltj@charclass']
-- sty : 0 (display or text), 1 (script), >=2 (scriptscript)
local function conv_jchar_to_hbox(head, sty)
- local p = head
- local bhead = head
- while p do
- if p.id == id_simple or p.id == id_accent then
- p.nucleus = conv_jchar_to_hbox_A(p.nucleus, sty)
- p.sub = conv_jchar_to_hbox_A(p.sub, sty + 1)
- p.sup = conv_jchar_to_hbox_A(p.sup, sty + 1)
- elseif p.id == id_choice then
- p.display = conv_jchar_to_hbox(p.display, 0)
- p.text = conv_jchar_to_hbox(p.text, 0)
- p.script = conv_jchar_to_hbox(p.script, 1)
- p.scriptscript = conv_jchar_to_hbox(p.scriptscript, 2)
- elseif p.id == id_frac then
- p.num = conv_jchar_to_hbox_A(p.num, sty + 1)
- p.denom = conv_jchar_to_hbox_A(p.denom, sty + 1)
- elseif p.id == id_radical then
- p.nucleus = conv_jchar_to_hbox_A(p.nucleus, sty)
- p.sub = conv_jchar_to_hbox_A(p.sub, sty + 1)
- p.sup = conv_jchar_to_hbox_A(p.sup, sty + 1)
- if p.degree then
- p.degree = conv_jchar_to_hbox_A(p.degree, sty + 1)
+ for p in node_traverse(head) do
+ local pid = getid(p)
+ if pid == id_simple or pid == id_accent then
+ setfield(p, 'nucleus', conv_jchar_to_hbox_A(getfield(p, 'nucleus'), sty))
+ setfield(p, 'sub', conv_jchar_to_hbox_A(getfield(p, 'sub'), sty+1))
+ setfield(p, 'sup', conv_jchar_to_hbox_A(getfield(p, 'sup'), sty+1))
+ elseif pid == id_choice then
+ setfield(p, 'display', conv_jchar_to_hbox_A(getfield(p, 'display'), 0))
+ setfield(p, 'text', conv_jchar_to_hbox_A(getfield(p, 'text'), 0))
+ setfield(p, 'script', conv_jchar_to_hbox_A(getfield(p, 'script'), 1))
+ setfield(p, 'scriptscript', conv_jchar_to_hbox_A(getfield(p, 'scriptscript'), 2))
+ elseif pid == id_frac then
+ setfield(p, 'num', conv_jchar_to_hbox_A(getfield(p, 'num'), sty+1))
+ setfield(p, 'denom', conv_jchar_to_hbox_A(getfield(p, 'denom'), sty+1))
+ elseif pid == id_radical then
+ setfield(p, 'nucleus', conv_jchar_to_hbox_A(getfield(p, 'nucleus'), sty))
+ setfield(p, 'sub', conv_jchar_to_hbox_A(getfield(p, 'sub'), sty+1))
+ setfield(p, 'sup', conv_jchar_to_hbox_A(getfield(p, 'sup'), sty+1))
+ if getfield(p, 'degree') then
+ setfield(p, 'degree', conv_jchar_to_hbox_A(getfield(p, 'degree'), sty + 1))
end
- elseif p.id == id_style then
- if p.style == "display'" or p.style == 'display'
- or p.style == "text'" or p.style == 'text' then
+ elseif pid == id_style then
+ local ps = getfield(p, 'style')
+ if ps == "display'" or ps == 'display'
+ or ps == "text'" or ps == 'text' then
sty = 0
- elseif p.style == "script'" or p.style == 'script' then
+ elseif ps == "script'" or ps == 'script' then
sty = 1
else sty = 2
end
end
- p = node.next(p)
end
return head
end
local MJT = luatexja.stack_table_index.MJT
local MJS = luatexja.stack_table_index.MJS
local MJSS = luatexja.stack_table_index.MJSS
+local capsule_glyph = ltjw.capsule_glyph
conv_jchar_to_hbox_A =
function (p, sty)
if not p then return nil
else
- local pid = p.id
+ local pid = getid(p)
if pid == id_sub_mlist then
- if p.head then
- p.head = conv_jchar_to_hbox(p.head, sty)
+ if getlist(p) then
+ setfield(p, 'head', conv_jchar_to_hbox(getlist(p), sty))
end
elseif pid == id_mchar then
local fam = has_attr(p, attr_jfam) or -1
- if (not is_math_letters[p.char]) and ltjc.is_ucs_in_japanese_char(p) and fam>=0 then
+ local pc = getchar(p)
+ if (not is_math_letters[pc]) and ltjc.is_ucs_in_japanese_char(to_node(p)) and fam>=0 then
local f = ltjs.get_penalty_table(MJT + 0x100 * sty + fam, -1, tex_getcount('ltj@@stack'))
if f ~= -1 then
local q = node_new(id_sub_box)
- local r = node_new(id_glyph); r.next = nil
- r.char = p.char; r.font = f; r.subtype = 256
+ local r = node_new(id_glyph); setfield(r, 'next', nil)
+ setfield(r, 'char', pc); setfield(r, 'font', f); setfield(r, 'subtype', 256)
local k = has_attr(r,attr_ykblshift) or 0
set_attr(r, attr_ykblshift, 0)
-- ltj-setwidth 内で実際の位置補正はおこなうので,補正量を退避
ltjw.head = r;
local met = ltjf_font_metric_table[f]
- ltjw.capsule_glyph(r, tex.mathdir , true, met, ltjf_find_char_class(p.char, met));
- q.head = ltjw.head; node_free(p); p=q;
- set_attr(q.head, attr_yablshift, k)
+ capsule_glyph(r, tex.mathdir , true, met, ltjf_find_char_class(pc, met));
+ setfield(q, 'head', ltjw.head); node_free(p); p=q;
+ set_attr(getlist(q), attr_yablshift, k)
end
end
- elseif pid == id_sub_box and p.head then
+ elseif pid == id_sub_box and getlist(p) then
-- \hbox で直に与えられた内容は上下位置を補正する必要はない
- set_attr(p.head, attr_icflag, PROCESSED)
+ set_attr(getlist(p), attr_icflag, PROCESSED)
end
end
return p
luatexbase.add_to_callback('mlist_to_hlist',
function (n, display_type, penalties)
- local head = conv_jchar_to_hbox(n, 0);
+ local head = to_node(conv_jchar_to_hbox(to_direct(n), 0))
head = node.mlist_to_hlist(head, display_type, penalties)
return head
end,'ltj.mlist_to_hlist', 1)
--
--- luatexja/setwidth.lua
+-- src/ltj-setwidth.lua
--
-luatexbase.provides_module({
- name = 'luatexja.setwidth',
- date = '2013/12/05',
- description = '',
-})
-module('luatexja.setwidth', package.seeall)
-local err, warn, info, log = luatexbase.errwarinf(_NAME)
luatexja.load_module('base'); local ltjb = luatexja.base
luatexja.load_module('jfont'); local ltjf = luatexja.jfont
-local node_type = node.type
-local node_new = node.new
-local node_tail = node.tail
-local node_next = node.next
-local has_attr = node.has_attribute
-local set_attr = node.set_attribute
-local node_insert_before = node.insert_before
-local node_insert_after = node.insert_after
+local Dnode = node.direct or node
+
+local setfield = (Dnode == node.direct) and Dnode.setfield or function(n, i, c) n[i] = c end
+local getfield = (Dnode == node.direct) and Dnode.getfield or function(n, i) return n[i] end
+local getid = (Dnode == node.direct) and Dnode.getid or function(n) return n.id end
+local getfont = (Dnode == node.direct) and Dnode.getfont or function(n) return n.font end
+local getlist = (Dnode == node.direct) and Dnode.getlist or function(n) return n.head end
+local getchar = (Dnode == node.direct) and Dnode.getlist or function(n) return n.char end
+local getsubtype = (Dnode == node.direct) and Dnode.getlist or function(n) return n.subtype end
+
+local node_traverse = Dnode.traverse
+local node_new = Dnode.new
+local node_remove = Dnode.remove
+local node_tail = Dnode.tail
+local node_next = Dnode.getnext
+local has_attr = Dnode.has_attribute
+local set_attr = Dnode.set_attribute
+local node_insert_before = Dnode.insert_before
+local node_insert_after = Dnode.insert_after
local round = tex.round
local id_glyph = node.id('glyph')
local IC_PROCESSED = luatexja.icflag_table.IC_PROCESSED
local PROCESSED_BEGIN_FLAG = luatexja.icflag_table.PROCESSED_BEGIN_FLAG
+local get_pr_begin_flag
do
local floor = math.floor
- function get_pr_begin_flag(p)
+ get_pr_begin_flag = function (p)
local i = has_attr(p, attr_icflag) or 0
return i - i%PROCESSED_BEGIN_FLAG
end
end
-local get_pr_begin_flag = get_pr_begin_flag
-head = nil;
+local ltjw = {}
+luatexja.setwidth = ltjw
luatexbase.create_callback("luatexja.set_width", "data",
function (fstable, fmtable, jchar_class)
return fstable
end)
+local call_callback = luatexbase.call_callback
local fshift = { down = 0, left = 0}
-- mode: true iff p will be always encapsuled by a hbox
-function capsule_glyph(p, dir, mode, met, class)
+local function capsule_glyph(p, dir, mode, met, class)
local char_data = met.char_type[class]
if not char_data then return node_next(p) end
- local fwidth, pwidth = char_data.width, p.width
+ local fwidth, pwidth = char_data.width, getfield(p, 'width')
fwidth = (fwidth ~= 'prop') and fwidth or pwidth
fshift.down = char_data.down; fshift.left = char_data.left
- fshift = luatexbase.call_callback("luatexja.set_width", fshift, met, class)
+ fshift = call_callback("luatexja.set_width", fshift, met, class)
local fheight, fdepth = char_data.height, char_data.depth
- if (mode or pwidth ~= fwidth or p.height ~= fheight or p.depth ~= fdepth) then
+ if (mode or pwidth ~= fwidth or getfield(p, 'height') ~= fheight or getfield(p, 'depth') ~= fdepth) then
local y_shift, ca
- = - p.yoffset + (has_attr(p,attr_ykblshift) or 0), char_data.align
- local q; head, q = node.remove(head, p)
- p.yoffset, p.next = -fshift.down, nil
+ = - getfield(p, 'yoffset') + (has_attr(p,attr_ykblshift) or 0), char_data.align
+ local q
+ ltjw.head, q = node_remove(ltjw.head, p)
+ setfield(p, 'yoffset', -fshift.down); setfield(p, 'next', nil)
if ca~='left' then
- p.xoffset = p.xoffset - fshift.left
- + (((ca=='right') and fwidth - pwidth) or round((fwidth - pwidth)*0.5))
+ setfield(p, 'xoffset', getfield(p, 'xoffset') - fshift.left
+ + (((ca=='right') and fwidth - pwidth) or round((fwidth - pwidth)*0.5)))
else
- p.xoffset = p.xoffset - fshift.left
+ setfield(p, 'xoffset', getfield(p, 'xoffset') - fshift.left)
end
local box = node_new(id_hlist);
- box.width, box.height, box.depth = fwidth, fheight, fdepth
- box.head, box.shift, box.dir = p, y_shift, (dir or 'TLT')
- --box.glue_set, box.glue_order = 0, 0 not needed
+ setfield(box, 'width', fwidth)
+ setfield(box, 'height', fheight)
+ setfield(box, 'depth', fdepth)
+ setfield(box, 'head', p)
+ setfield(box, 'shift', y_shift)
+ setfield(box, 'dir', dir or 'TLT')
set_attr(box, attr_icflag, PACKED + get_pr_begin_flag(p))
- head = q and node_insert_before(head, q, box)
- or node_insert_after(head, node_tail(head), box)
+ ltjw.head = q and node_insert_before(ltjw.head, q, box)
+ or node_insert_after(ltjw.head, node_tail(ltjw.head), box)
return q
else
set_attr(p, attr_icflag, PROCESSED + get_pr_begin_flag(p))
- p.xoffset = p.xoffset - fshift.left
- p.yoffset = p.yoffset - (has_attr(p, attr_ykblshift) or 0) - fshift.down
+ setfield(p, 'xoffset', getfield(p, 'xoffset') - fshift.left)
+ setfield(p, 'yoffset', getfield(p, 'yoffset') - (has_attr(p, attr_ykblshift) or 0) - fshift.down)
return node_next(p)
end
end
+luatexja.setwidth.capsule_glyph = capsule_glyph
-function set_ja_width(ahead, dir)
- local p = ahead; head = ahead
+function luatexja.setwidth.set_ja_width(ahead, dir)
+ local p = ahead; ltjw.head = p
local m = false -- is in math mode?
while p do
- local pid = p.id
+ local pid = getid(p)
if (pid==id_glyph)
and ((has_attr(p, attr_icflag) or 0)%PROCESSED_BEGIN_FLAG)<=0 then
- local pf = p.font
+ local pf = getfont(p)
if pf == has_attr(p, attr_curjfnt) then
p = capsule_glyph(p, dir, false, ltjf_font_metric_table[pf],
has_attr(p, attr_jchar_class))
else
set_attr(p, attr_icflag, PROCESSED + get_pr_begin_flag(p))
- p.yoffset = p.yoffset - (has_attr(p,attr_yablshift) or 0); p = node_next(p)
+ setfield(p, 'yoffset',
+ getfield(p, 'yoffset') - (has_attr(p,attr_yablshift) or 0))
+ p = node_next(p)
end
- elseif p.id==id_math then
- m = (p.subtype==0); p = node_next(p)
+ elseif pid==id_math then
+ m = (getsubtype(p)==0); p = node_next(p)
else
if m then
-- 数式の位置補正
if pid==id_hlist or pid==id_vlist then
if (has_attr(p, attr_icflag) or 0) ~= PROCESSED then
- p.shift = p.shift + (has_attr(p,attr_yablshift) or 0)
+ setfield(p, 'shift', getfield(p, 'shift') + (has_attr(p,attr_yablshift) or 0))
end
elseif pid==id_rule then
if (has_attr(p, attr_icflag) or 0) ~= PROCESSED then
local v = has_attr(p,attr_yablshift) or 0
- p.height = p.height - v; p.depth = p.depth + v
+ setfield(p, 'height', getfield(p, 'height')-v)
+ setfield(p, 'depth', getfield(p, 'depth')+v)
set_attr(p, attr_icflag, PROCESSED + get_pr_begin_flag(p))
end
end
end
-- adjust attr_icflag
tex.setattribute('global', attr_icflag, 0)
- return head
+ return ltjw.head
end
+