+ function luatexja.direction.set_list_direction_hook(v)
+ local lv = tex_nest.ptr -- must be >= 1
+ if not v then
+ v = get_dir_count()
+ if abs(tex_nest[lv-1].mode) == ltjs.mmode and v == dir_tate then
+ v = dir_utod
+ end
+ elseif v=='adj' then
+ v = get_adjust_dir_count()
+ end
+ local h = to_direct(tex_nest[lv].head)
+ local w = node_new(id_whatsit, sid_user)
+ setfield(w, 'next', nil)
+ setfield(w, 'user_id', DIR)
+ setfield(w, 'type', 110)
+ set_attr(w, attr_dir, v)
+ insert_after(h, h, w)
+ tex_nest[lv].tail = to_node(node_tail(w))
+ tex_set_attr('global', attr_icflag, 0)
+ tex_set_attr('global', attr_dir, 0)
+ end
+
+ local function set_list_direction(v, name)
+ local lv = tex_nest.ptr
+ if not v then
+ v,name = get_dir_count(), nil
+ if lv>=1 and abs(tex_nest[lv-1].mode) == ltjs.mmode and v == dir_tate then
+ v = dir_utod
+ end
+ elseif v=='adj' then
+ v,name = get_adjust_dir_count(), nil
+ end
+ if tex.currentgrouptype==6 then
+ ltjb.package_error(
+ 'luatexja',
+ "You can't use `\\" .. name .. "' in an align",
+ "To change direction in an align, \n"
+ .. "you shold use \\hbox or \\vbox.")
+ else
+ local h = (lv==0) and tex.lists.page_head or tex_nest[lv].head.next
+ local flag,w = test_list(h,lv)
+ if flag==0 then
+ if lv==0 and not page_direction then
+ page_direction = v -- for first call of \yoko (in luatexja-core.sty)
+ else
+ ltjb.package_error(
+ 'luatexja',
+ "Use `\\" .. tostring(name) .. "' at top of list",
+ 'Direction change command by LuaTeX-ja is available\n'
+ .. 'only when the current list is null.')
+ end
+ elseif flag==1 then
+ node_set_attr(w, attr_dir, v)
+ if lv==0 then page_direction = v end
+ else
+ local w = node_new(id_whatsit, sid_user)
+ setfield(w, 'next', nil)
+ setfield(w, 'user_id', DIR)
+ setfield(w, 'type', 110)
+ set_attr(w, attr_dir, v)
+ Dnode.write(w)
+ if lv==0 then page_direction = v end
+ 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
+
+-- ボックスに dir whatsit を追加
+local function create_dir_whatsit(hd, gc, new_dir)
+ if getid(hd)==id_whatsit and
+ getsubtype(hd)==sid_user and getfield(hd, 'user_id')==DIR then
+ set_attr(hd, attr_icflag,
+ get_attr_icflag(hd) + PROCESSED_BEGIN_FLAG)
+ tex_set_attr('global', attr_icflag, 0)
+ return hd
+ 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, new_dir)
+ set_attr(w, attr_icflag, PROCESSED_BEGIN_FLAG)
+ set_attr(hd, attr_icflag,
+ (has_attr(hd, attr_icflag) or 0)%PROCESSED_BEGIN_FLAG
+ + PROCESSED_BEGIN_FLAG)
+ tex_set_attr('global', attr_dir, 0)
+ tex_set_attr('global', attr_icflag, 0)
+ return w
+ end
+end
+
+-- hpack_filter, vpack_filter, post_line_break_filter
+-- の結果を組方向を明示するため,先頭に dir_node を設置
+do
+ local function create_dir_whatsit_hpack(h, gc)
+ local hd = to_direct(h)
+ 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
+ else
+ adjust_badness(hd)
+ return to_node(create_dir_whatsit(hd, gc, ltjs.list_dir))
+ end
+ end
+
+ luatexbase.add_to_callback('hpack_filter',
+ create_dir_whatsit_hpack, 'ltj.create_dir_whatsit', 10000)
+end
+
+do
+ local function create_dir_whatsit_parbox(h, gc)
+ stop_time_measure('tex_linebreak')
+ -- start 側は ltj-debug.lua に
+ local new_dir, hd = ltjs.list_dir, to_direct(h)
+ for line in traverse_id(id_hlist, hd) do
+ local nh = getlist(line)
+ setfield(line, 'head', create_dir_whatsit(nh, gc, new_dir) )
+ --set_attr(line, attr_dir, new_dir)
+ end
+ tex_set_attr('global', attr_dir, 0)
+ return h
+ end