OSDN Git Service

luatexja-core.sty: insert \leavevmode in the def. of \ltjjachar and \ltjalchar
[luatex-ja/luatexja.git] / src / ltj-jfmglue.lua
index 1e7cca8..019e24a 100644 (file)
@@ -3,7 +3,7 @@
 --
 luatexbase.provides_module({
   name = 'luatexja.jfmglue',
-  date = '2020-07-30',
+  date = '2020-12-22',
   description = 'Insertion process of JFM glues, [x]kanjiskip and others',
 })
 luatexja.jfmglue = luatexja.jfmglue or {}
@@ -78,6 +78,7 @@ local FROM_JFM     = luatexja.icflag_table.FROM_JFM
 local PROCESSED    = luatexja.icflag_table.PROCESSED
 local IC_PROCESSED = luatexja.icflag_table.IC_PROCESSED
 local BOXBDD       = luatexja.icflag_table.BOXBDD
+local SPECIAL_JAGLUE = luatexja.icflag_table.SPECIAL_JAGLUE
 local PROCESSED_BEGIN_FLAG = luatexja.icflag_table.PROCESSED_BEGIN_FLAG
 
 local attr_icflag = luatexbase.attributes['ltj@icflag']
@@ -459,7 +460,7 @@ calc_np_auxtable = {
       if lps==sid_user then
          if getfield(lp, 'user_id')==luatexja.userid_table.IHB then
             local lq = node_next(lp);
-            head = node_remove(head, lp); node_free(lp); non_ihb_flag = false
+            head = node_remove(head, lp); node_free(lp); non_ihb_flag = getfield(lp, 'value')~=1
             return false, lq;
          elseif getfield(lp, 'user_id')==luatexja.userid_table.JA_AL_BDD then
             local lq = node_next(lp);
@@ -499,7 +500,11 @@ calc_np_auxtable = {
    end,
    [id_glue] = function(lp)
       Np.first, Np.nuc, Np.last = (Np.first or lp), lp, lp;
-      Np.id = getid(lp); set_attr(lp, attr_icflag, PROCESSED)
+      Np.id = getid(lp); 
+      local f = luatexbase.call_callback("luatexja.jfmglue.special_jaglue", lp)
+      if f then
+         set_attr(lp, attr_icflag, PROCESSED)
+      end
       return true, node_next(lp)
    end,
    [id_disc] = function(lp)
@@ -562,7 +567,7 @@ function calc_np(last, lp)
    while lp ~= last  do
       local lpa = has_attr(lp, attr_icflag) or 0
       -- unbox 由来ノードの検出
-      if lpa>=PACKED then
+      if (lpa>=PACKED) and (lpa%PROCESSED_BEGIN_FLAG<=BOXBDD) then
          if lpa%PROCESSED_BEGIN_FLAG == BOXBDD then
             local lq = node_next(lp)
             head = node_remove(head, lp); node_free(lp); lp = lq
@@ -1095,13 +1100,15 @@ local adjust_nq
 do
    local adjust_nq_aux = {
       [id_glyph] = function() after_alchar(Nq) end, -- after_alchar(Nq)
-      [id_hlist]  = function() after_hlist(Nq) end,
+      [id_hlist] = function() after_hlist(Nq) end,
       [id_pbox]  = function() after_hlist(Nq) end,
       [id_disc]  = function() after_hlist(Nq) end,
-      [id_pbox_w]  = function()
-                        luatexbase.call_callback("luatexja.jfmglue.whatsit_after",
-                                                 false, Nq, Np)
-                     end,
+      [id_glue]  = function() 
+                      luatexbase.call_callback("luatexja.jfmglue.special_jaglue_after", Nq.nuc)
+                   end,
+      [id_pbox_w]= function()
+                      luatexbase.call_callback("luatexja.jfmglue.whatsit_after", false, Nq, Np)
+                   end,
    }
 
    adjust_nq = function()
@@ -1220,27 +1227,10 @@ do
    end
 end
 
-local ensure_tex_attr = ltjb.ensure_tex_attr
-local function cleanup(mode, TEMP)
-   -- luatexja.ext_show_node_list(to_node(head), '> ', print)
-   -- adjust attr_icflag for avoiding error
-   if tex.getattribute(attr_icflag)~=0 then ensure_tex_attr(attr_icflag, 0) end
-   node_free(kanji_skip); 
-   node_free(xkanji_skip); node_free(TEMP)
-   
-   if mode then
-      local h = node_next(head)
-      if getid(h) == id_penalty and getfield(h, 'penalty') == 10000 then
-         h = node_next(h)
-         if getid(h) == id_glue and getsubtype(h) == 15 and not node_next(h) then
-            return false
-         end
-      end
-   end
-   return head
-end
 -------------------- 外部から呼ばれる関数
 
+local ensure_tex_attr = ltjb.ensure_tex_attr
+local tex_getattr = tex.getattribute
 -- main interface
 function luatexja.jfmglue.main(ahead, mode, dir)
    if not ahead then return ahead end
@@ -1267,9 +1257,11 @@ function luatexja.jfmglue.main(ahead, mode, dir)
       end
       handle_list_tail(mode, last)
    end
-   --luatexja.ext_show_node_list(to_node(ahead ), '>A ', print)
-   --print()
-   return cleanup(mode, TEMP)
+   -- adjust attr_icflag for avoiding error
+   if tex_getattr(attr_icflag)~=0 then ensure_tex_attr(attr_icflag, 0) end
+   node_free(kanji_skip); 
+   node_free(xkanji_skip); node_free(TEMP)
+   return head
 end
 end
 
@@ -1280,14 +1272,20 @@ do
    local node_prev = node.direct.getprev
    local node_write = node.direct.write
 
-   -- \inhibitglue
-   function luatexja.jfmglue.create_inhibitglue_node()
+   -- \inhibitglue, \disinhibitglue
+   local function ihb_node(v)
       local tn = node_new(id_whatsit, sid_user)
       setfield(tn, 'user_id', IHB)
       setfield(tn, 'type', 100)
-      setfield(tn, 'value', 1)
+      setfield(tn, 'value', v)
       node_write(tn)
    end
+   function luatexja.jfmglue.create_inhibitglue_node()
+      ihb_node(1)
+   end
+   function luatexja.jfmglue.create_disinhibitglue_node()
+      ihb_node(0)
+   end
 
    -- Node for indicating beginning of a paragraph
    -- (for ltjsclasses)
@@ -1361,8 +1359,117 @@ do
                               "luatexja.beginpar.np_info", 1)
    luatexbase.add_to_callback("luatexja.jfmglue.whatsit_after", whatsit_after_callback,
                               "luatexja.beginpar.np_info_after", 1)
+end
 
+do
+   local node_prev = node.direct.getprev
+   local node_write = node.direct.write
+   local XKANJI_SKIP   = luatexja.icflag_table.XKANJI_SKIP
+   local XKANJI_SKIP_JFM   = luatexja.icflag_table.XKANJI_SKIP_JFM
+   local KANJI_SKIP   = luatexja.icflag_table.KANJI_SKIP
+   local KANJI_SKIP_JFM   = luatexja.icflag_table.KANJI_SKIP_JFM
+   local XSK  = luatexja.stack_table_index.XSK
+   local KSK  = luatexja.stack_table_index.KSK
+   local attr_yablshift = luatexbase.attributes['ltj@yablshift']
+   local attr_tablshift = luatexbase.attributes['ltj@tablshift']
+   local getcount, abs, scan_keyword = tex.getcount, math.abs, token.scan_keyword
+   local get_current_jfont
+   do
+       local attr_curjfnt = luatexbase.attributes['ltj@curjfnt']
+       local attr_curtfnt = luatexbase.attributes['ltj@curtfnt']
+       local dir_tate = luatexja.dir_table.dir_tate
+       local get_dir_count = ltjd.get_dir_count        
+       function get_current_jfont()
+           return tex.getattribute((get_dir_count()==dir_tate) and attr_curtfnt or attr_curjfnt)
+       end
+   end
+   -- \insertxkanjiskip
+   -- SPECIAL_JAGLUE のノード:
+   -- * (X)KANJI_SKIP(_JFM): その場で値が決まっている
+   -- * PROCESSED_BEGIN_FLAG + (X)KANJI_SKIP: 段落終了時に決める
+   local function insert_k_skip_common(ind, name, ica, icb)
+       if abs(tex.nest[tex.nest.ptr].mode) ~= ltjs.hmode then return end
+       local g = node_new(id_glue); set_attr(g, attr_icflag, SPECIAL_JAGLUE)
+       local is_late = scan_keyword("late")
+       if not is_late then
+           local st = ltjs.get_stack_skip(ind, getcount('ltj@@stack'))
+           if st.width==1073741823 then
+               local bk = ltjf_font_metric_table[get_current_jfont()][name]
+               if bk then
+                   setglue(g, bk[1] or 0, bk[2] or 0, bk[3] or 0, 0, 0)
+               end
+               set_attr(g, attr_yablshift, icb); node_write(g); return
+           end
+           setglue(g, st.width, st.stretch, st.shrink, st.stretch_order, st.shrink_order)
+           set_attr(g, attr_yablshift, ica)
+       else
+           set_attr(g, attr_yablshift, PROCESSED_BEGIN_FLAG + ica)
+           set_attr(g, attr_tablshift, get_current_jfont())               
+       end
+       node_write(g)
+   end
+   function luatexja.jfmglue.insert_xk_skip()
+       insert_k_skip_common(XSK, "xkanjiskip", XKANJI_SKIP, XKANJI_SKIP_JFM)
+   end
+   function luatexja.jfmglue.insert_k_skip()
+       insert_k_skip_common(KSK, "kanjiskip", KANJI_SKIP, KANJI_SKIP_JFM)
+   end
+   -- callback
+   local getglue = luatexja.getglue
+   local function special_jaglue(lx)
+       local lxi = get_attr_icflag(lx)
+       if lxi==SPECIAL_JAGLUE then
+           non_ihb_flag = false; return false
+       else
+           return lx
+       end
+   end
+   local function special_jaglue_after(lx)
+       if get_attr_icflag(lx)==SPECIAL_JAGLUE then
+           lxi=has_attr(lx, attr_yablshift)
+           if lxi>=PROCESSED_BEGIN_FLAG then
+               lxi = lxi%PROCESSED_BEGIN_FLAG
+               if lxi == KANJI_SKIP then
+                   local w, st, sh, sto, sho = getglue(kanji_skip)
+                   if w~=1073741823 then
+                       setglue(lx, w, st, sh, sto, sho); set_attr(lx, attr_icflag, KANJI_SKIP)
+                   else
+                       local m = ltjf_font_metric_table[has_attr(lx, attr_tablshift)]
+                       local bk = m.kanjiskip or null_skip_table
+                       setglue(lx, bk[1], bk[2], bk[3], 0, 0)
+                       set_attr(lx, attr_icflag, KANJI_SKIP_JFM)
+                   end
+               elseif lxi == XKANJI_SKIP then
+                   local w, st, sh, sto, sho = getglue(xkanji_skip)
+                   if w~=1073741823 then
+                       setglue(lx, w, st, sh, sto, sho); set_attr(lx, attr_icflag, XKANJI_SKIP)
+                   else
+                       local m = ltjf_font_metric_table[has_attr(lx, attr_tablshift)]
+                       local bk = m.xkanjiskip or null_skip_table
+                       setglue(lx, bk[1], bk[2], bk[3], 0, 0)
+                       set_attr(lx, attr_icflag, XKANJI_SKIP_JFM)
+                   end
+               end
+           else
+               set_attr(lx, attr_icflag, lxi)
+           end
+           Np.first = lx
+           if node_prev(lx) then
+               local lxp = node_prev(lx)
+               if lxp and getid(lxp)==id_penalty and get_attr_icflag(lxp)==KINSOKU then
+                   Bp[#Bp+1]=lxp
+               end
+           end
+           non_ihb_flag = false; return false
+       end
+       return true
+   end
+   luatexbase.create_callback("luatexja.jfmglue.special_jaglue", "list",
+                              special_jaglue)
+   luatexbase.create_callback("luatexja.jfmglue.special_jaglue_after", "list",
+                              special_jaglue_after)
 end
 
+
 luatexja.jfmglue.after_hlist = after_hlist
 luatexja.jfmglue.check_box_high = check_box_high