luatexja.load_module('base'); local ltjb = luatexja.base
luatexja.load_module('stack'); local ltjs = luatexja.stack
-luatexja.load_module('rmlgbm'); local ltjr = luatexja.rmlgbm
luatexja.direction = {}
local attr_dir = luatexbase.attributes['ltj@dir']
local PROCESSED = luatexja.icflag_table.PROCESSED
local PROCESSED_BEGIN_FLAG = luatexja.icflag_table.PROCESSED_BEGIN_FLAG
local PACKED = luatexja.icflag_table.PACKED
-local STCK = luatexja.userid_table.STCK
local DIR = luatexja.userid_table.DIR
local dir_tate = luatexja.dir_table.dir_tate
local dir_yoko = luatexja.dir_table.dir_yoko
local dir_math_mod = luatexja.dir_table.dir_math_mod
local dir_node_auto = luatexja.dir_table.dir_node_auto
local dir_node_manual = luatexja.dir_table.dir_node_manual
+local function get_attr_icflag(p)
+ return (has_attr(p, attr_icflag) or 0) % PROCESSED_BEGIN_FLAG
+end
local page_direction
--
local function get_dir_count_inner(h)
if h then
if h.id==id_whatsit and h.subtype==sid_user and h.user_id==DIR then
- local ic = node.has_attribute(h, attr_icflag)
+ local ic = node.has_attribute(h, attr_icflag) or 0
return (ic<PROCESSED_BEGIN_FLAG)
and (node.has_attribute(h,attr_dir)%dir_node_auto) or 0
else
do
local node_next = node.next
local node_set_attr = node.set_attribute
+ local node_traverse = node.traverse
+ local STCK = luatexja.userid_table.STCK
+ local IHB = luatexja.userid_table.IHB
+
+ local function test_list(h, lv)
+ if not h then
+ return 2 -- need to create dir_whatsit
+ else
+ local flag = 2 -- need to create dir_whatsit
+ local w
+ for p in node_traverse(h) do
+ if p.id==id_whatsit then
+ if p.subtype==sid_user then
+ local uid= p.user_id
+ if uid==DIR then
+ flag = 1; w = w or p -- found
+ elseif not(uid==IHB or uid==STCK) then
+ flag = 0; break -- error
+ end
+ else
+ flag = 0; break
+ end
+ else
+ flag = 0; break
+ end
+ end
+ if flag==1 then -- move dir_whatsit w
+ return 1,w -- TODO
+ else
+ return flag
+ end
+ end
+ end
local function set_list_direction(v, name)
- local lv, w = tex_nest.ptr, tex.lists.page_head
+ 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
"To change direction in an align, \n"
.. "you shold use \\hbox or \\vbox.")
else
- local w = (lv==0) and tex.lists.page_head or tex_nest[lv].head.next
- if w then
- if (not w.next) and
- w.id==id_whatsit and w.subtype==sid_user and w.user_id==DIR then
- node_set_attr(w, attr_dir, v)
- if lv==0 then page_direction = v end
- elseif lv==0 and not page_direction then
+ 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(
'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)
if getid(hd)==id_whatsit and
getsubtype(hd)==sid_user and getfield(hd, 'user_id')==DIR then
set_attr(hd, attr_icflag,
- (has_attr(hd, attr_icflag) or 0)%PROCESSED_BEGIN_FLAG
- + PROCESSED_BEGIN_FLAG)
+ get_attr_icflag(hd) + PROCESSED_BEGIN_FLAG)
tex_set_attr('global', attr_icflag, 0)
return hd
else
local x, new_dir = hd, ltjs.list_dir or dir_yoko
while x do
local xid = getid(x)
- if (xid==id_hlist and has_attr(x, attr_icflag)%PROCESSED_BEGIN_FLAG~=PACKED)
+ if (xid==id_hlist and get_attr_icflag(x)~=PACKED)
or xid==id_vlist then
hd, x = make_dir_whatsit(hd, x, new_dir, 'process_dir_node:' .. gc)
else
end
end
--- 縦書き用字形への変換テーブル
-local font_vert_table = {} -- key: fontnumber
-do
- local font_vert_basename = {} -- key: basename
- local function add_feature_table(tname, src, dest)
- for i,v in pairs(src) do
- if type(v.slookups)=='table' then
- local s = v.slookups[tname]
- if s and not dest[i] then
- dest[i] = s
- end
- end
- end
- end
-
- local function prepare_vert_data(n, id)
- -- test if already loaded
- if type(id)=='number' then -- sometimes id is an integer
- font_vert_table[n] = font_vert_table[id]; return
- elseif (not id) or font_vert_table[n] then return
- end
- local fname = id.filename
- local bname = file.basename(fname)
- if not fname then
- font_vert_table[n] = {}; return
- elseif font_vert_basename[bname] then
- font_vert_table[n] = font_vert_basename[bname]; return
- end
- local vtable = {}
- local a = id.resources.sequences
- if a then
- local s = id.shared.rawdata.descriptions
- for i,v in pairs(a) do
- if v.features.vert or v.features.vrt2 then
- add_feature_table(v.subtables[1], s, vtable)
- end
- end
- end
- font_vert_basename[bname] = vtable
- font_vert_table[n] = vtable
- end
- -- 縦書き用字形への変換
- function luatexja.direction.get_vert_glyph(n, chr)
- local fn = font_vert_table[n]
- return fn and fn[chr] or chr
- end
- luatexbase.add_to_callback('luatexja.define_font',
- function (res, name, size, id)
- prepare_vert_data(id, res)
- end,
- 'prepare_vert_data', 1)
-
- local function a (n, dat) font_vert_table[n] = dat end
- luatexja.rmlgbm.vert_addfunc = a
-
-end
-
-- PACKED の hbox から文字を取り出す
-- luatexja.jfmglue.check_box などで使用
do
function luatexja.direction.remove_end_whatsit()
local h=tex.lists.page_head
- if (not h.next) and
+ if h and (not h.next) and
h.id==id_whatsit and h.subtype==sid_user and
h.user_id == DIR then
tex.lists.page_head = nil