OSDN Git Service

More LaTeX codes for vertical writing
[luatex-ja/luatexja.git] / src / ltj-direction.lua
index c05bc35..4057de5 100644 (file)
@@ -4,7 +4,6 @@
 
 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']
@@ -50,7 +49,6 @@ local tex_set_attr = tex.setattribute
 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
@@ -59,6 +57,9 @@ local dir_utod = luatexja.dir_table.dir_utod
 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
 --
@@ -81,7 +82,7 @@ do
    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
@@ -121,8 +122,41 @@ end
 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
@@ -138,13 +172,10 @@ do
                 "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(
@@ -153,6 +184,9 @@ do
                  '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)
@@ -174,8 +208,7 @@ 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, 
-              (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
@@ -605,7 +638,7 @@ do
       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
@@ -844,63 +877,6 @@ do
    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
@@ -982,7 +958,7 @@ 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