local dir_node_manual = luatexja.dir_table.dir_node_manual
-
-local function get_dir_count()
- return tex_getcount('ltj@dir@count')
-end
-luatexja.direction.get_dir_count = get_dir_count
-
+local get_dir_count
-- \tate, \yoko
do
- local node_next = node.next
- local node_set_attr = node.set_attribute
- local function set_list_direction(v, name)
- local lv, w = tex.nest[tex.nest.ptr], tex.lists.page_head
- if lv.mode == 1 and w then
- if w.id==id_whatsit and w.subtype==sid_user
- and w.user_id==DIR then
- node_set_attr(w, attr_dir, v)
-
- end
- else
- local w = node_next(to_direct(lv.head))
- if to_node(w) then
- if getid(w)==id_whatsit and getsubtype(w)==sid_user
- and getfield(w, 'user_id')==DIR then
- set_attr(w, attr_dir, v)
- tex_set_attr('global', attr_dir, 0)
- else
+ function get_dir_count()
+ return tex_getcount('ltj@dir@count')
+ end
+ luatexja.direction.get_dir_count = get_dir_count
+
+ local node_next = node.next
+ local node_set_attr = node.set_attribute
+ local function set_list_direction(v, name)
+ local lv, w = tex.nest[tex.nest.ptr], tex.lists.page_head
+ if lv.mode == 1 and w then
+ if w.id==id_whatsit and w.subtype==sid_user
+ and w.user_id==DIR then
+ node_set_attr(w, attr_dir, v)
+ end
+ else
+ local w = node_next(lv.head)
+ if w then
+ w = to_direct(w)
+ if getid(w)==id_whatsit and getsubtype(w)==sid_user
+ and getfield(w, 'user_id')==DIR then
+ set_attr(w, attr_dir, v)
+ else
ltjb.package_error(
'luatexja',
"Use `\\" .. name .. "' at top of list",
'Direction change command by LuaTeX-ja is available\n'
- .. 'only when the current list is null.')
- end
- else
- local w = node_new(id_whatsit, sid_user)
- setfield(w, 'next', hd)
- setfield(w, 'user_id', DIR)
- setfield(w, 'type', 110)
- set_attr(w, attr_dir, v)
- Dnode.write(w)
- tex_set_attr('global', attr_dir, 0)
- end
- tex_set_attr('global', attr_icflag, 0)
- end
- end
- luatexja.direction.set_list_direction = set_list_direction
+ .. 'only when the current list is null.')
+ end
+ else
+ local w = node_new(id_whatsit, sid_user)
+ setfield(w, 'next', hd)
+ setfield(w, 'user_id', DIR)
+ setfield(w, 'type', 110)
+ set_attr(w, attr_dir, v)
+ Dnode.write(w)
+ end
+ tex_set_attr('global', attr_icflag, 0)
+ end
+ tex_set_attr('global', attr_dir, 0)
+ end
+ luatexja.direction.set_list_direction = set_list_direction
+end
+
+function luatexja.direction.freeze_list_dir()
+ local w = to_direct(tex.nest[tex.nest.ptr].tail)
+ set_attr(w, attr_dir, -has_attr(w, attr_dir))
end
-- ボックスに dir whatsit を追加
luatexbase.add_to_callback('hpack_filter',
create_dir_whatsit_hpack, 'ltj.create_dir_whatsit', 10000)
+ local wh = {}
+ local id_glue, sid_parskip = node.id('glue'), 3
local function create_dir_whatsit_vbox(h, gc)
- local hd= to_direct(h)
+ local hd = to_direct(h)
ltjs.list_dir = get_dir_count()
- if getid(hd)==id_whatsit and getsubtype(hd)==sid_user
- and getfield(hd, 'user_id')==DIR then
- ltjs.list_dir = has_attr(hd, attr_dir)
- return h
- elseif gc=='fin_row' or gc == 'preamble' then
+ -- remove dir whatsit
+ for x in traverse_id(id_whatsit, hd) do
+ if getsubtype(x)==sid_user and getfield(x, 'user_id')==DIR then
+ wh[#wh+1]=x
+ end
+ end
+ if hd==wh[1] then
+ ltjs.list_dir =has_attr(hd,attr_dir)
+ local x = node_next(hd)
+ if getid(x)==id_glue and getsubtype(x)==sid_parskip then
+ node_remove(hd,x); node_free(x)
+ end
+ end
+ for i=1,#wh do hd = node_remove(hd, wh[i]); node_free(wh[i]); wh[i] = nil end
+ if gc=='fin_row' or gc == 'preamble' then
if hd then
set_attr(hd, attr_icflag, PROCESSED_BEGIN_FLAG)
tex_set_attr('global', attr_icflag, 0)
end
- return h
+ return to_node(hd)
+ elseif gc=='vtop' then
+ local w = create_dir_whatsit(hd, gc, ltjs.list_dir)
+ -- move dir whatsit after hd
+ local n = getfield(hd, 'next')
+ setfield(hd, 'next', w); setfield(w, 'next', n)
+ return to_node(hd)
else
return to_node(create_dir_whatsit(hd, gc, ltjs.list_dir))
end
for line in traverse_id(id_hlist, hd) do
set_attr(line, attr_dir, new_dir)
end
+ tex_set_attr('global', attr_dir, 0)
return to_node(create_dir_whatsit(hd, gc, new_dir))
end
- luatexbase.add_to_callback('post_linebreak_filter',
+ luatexbase.add_to_callback('post_linebreak_filter',
create_dir_whatsit_parbox, 'ltj.create_dir_whatsit', 10000)
end
-- 2nd ret val はその DIR whatsit
local function get_box_dir(b, default)
local dir = has_attr(b, attr_dir) or 0
- local bh = getlist(b)
+ local bh = getfield(b,'head')
+ -- b は insert node となりうるので getlist() は使えない
local c
- if bh and getid(bh)==id_whatsit
- and getsubtype(bh)==sid_user and getfield(bh, 'user_id')==DIR then
- c = bh
- if dir==0 then
- dir = has_attr(bh, attr_dir)
- set_attr(b, attr_dir, dir)
- tex_set_attr('global', attr_dir, 0)
+ for i=1,2 do
+ if bh and getid(bh)==id_whatsit
+ and getsubtype(bh)==sid_user and getfield(bh, 'user_id')==DIR then
+ c = bh
+ if dir==0 then
+ dir = has_attr(bh, attr_dir)
+ set_attr(b, attr_dir, dir)
+ tex_set_attr('global', attr_dir, 0)
+ end
end
+ bh = node_next(bh)
end
return (dir==0 and default or dir), c
end
+function luatexja.direction.check_dir(reg_num)
+ local list_dir = get_dir_count()
+ local b = tex.getbox(reg_num)
+ if b then
+ local box_dir = get_box_dir(to_direct(b), dir_yoko)
+ if box_dir%dir_node_auto ~= list_dir%dir_node_auto then
+ ltjb.package_error(
+ 'luatexja',
+ "Incompatible direction list can't be unboxed",
+ 'I refuse to unbox a box in differrent direction.')
+ end
+ end
+end
+
-- dir_node に包まれている「本来の中身」を取り出し,
-- dir_node を全部消去
local function unwrap_dir_node(b, head, box_dir)
local db = node_new(getid(b))
set_attr(db, attr_dir,
new_dir + (is_manual and dir_node_manual or dir_node_auto))
+ tex_set_attr('global', attr_dir, 0)
set_attr(db, attr_icflag, PROCESSED)
set_attr(b, attr_icflag, PROCESSED)
setfield(db, 'dir', getfield(b, 'dir'))
setfield(s, key, tex.getdimen('ltj@tempdima'))
if b_dir<dir_node_manual then
set_attr(s, attr_dir, b_dir%dir_node_auto + dir_node_manual)
- tex_set_attr('global', attr_dir, 0)
end
else
local sid, sl = getid(s), getlist(s)
luatexja.direction.set_box_dim = set_box_dim
end
+-- \ifydir, \iftdir, \ifddir
+do
+ local cat_lp = luatexbase.catcodetables['latex-package']
+ local getbox = tex.getbox
+ local function dir_conditional(n, mode)
+ local s = getbox(n)
+ local res = false
+ if s then
+ s = to_direct(s)
+ local b_dir = get_box_dir(s, dir_yoko)
+ if b_dir<dir_node_auto then
+ res = (b_dir==mode)
+ else
+ local b_dir = get_box_dir(
+ node_next(node_next(node_next(getlist(s)))), dir_yoko)
+ res = (b_dir==mode)
+ end
+ end
+ tex.sprint(cat_lp, '\\if' .. tostring(res))
+ end
+ luatexja.direction.dir_conditional = dir_conditional
+end
+
-- 縦書き用字形への変換テーブル
local font_vert_table = {} -- key: fontnumber
do
end
luatexja.direction.glyph_from_packed = glyph_from_packed
end
+
+-- adjust and insertion
+local id_adjust = node.id('adjust')
+function luatexja.direction.check_adjust_direction()
+ local list_dir = tex_getcount('ltj@adjdir@count')
+ local a = tex.nest[tex.nest.ptr].tail
+ local ad = to_direct(a)
+ if a and getid(ad)==id_adjust then
+ local adj_dir = get_box_dir(ad)
+ if list_dir~=adj_dir then
+ ltjb.package_error(
+ 'luatexja',
+ 'Direction Incompatible',
+ "\\vadjust's argument and outer vlist must have same direction.")
+ Dnode.last_node()
+ end
+ end
+end