OSDN Git Service

a [x]kanjiskip glue whose spec is from JFM has distinguished attr_icflag value
authorHironori Kitagawa <h_kitagawa2001@yahoo.co.jp>
Sun, 26 Jan 2014 06:50:08 +0000 (15:50 +0900)
committerHironori Kitagawa <h_kitagawa2001@yahoo.co.jp>
Sun, 26 Jan 2014 06:50:08 +0000 (15:50 +0900)
icflag_table.KANJI_SKIP      = 9
icflag_table.KANJI_SKIP_JFM  = 10  -- NEW
icflag_table.XKANJI_SKIP     = 11  -- old: 10
icflag_table.XKANJI_SKIP_JFM = 12  -- NEW
icflag_table.PROCESSED       = 13  -- old: 11
icflag_table.IC_PROCESSED    = 14  -- old: 12
icflag_table.PROCESSED_BEGIN_FLAG = 128 -- old: 32

Memory leak which is caused by luatexja-adjust (ltj-adjust.lua) is now
resolved in this commit, but perhaps there is better solution.

src/addons/luatexja-adjust.sty
src/ltj-adjust.lua
src/ltj-jfmglue.lua
src/luatexja.lua

index a926210..cdfad90 100644 (file)
@@ -82,7 +82,6 @@
 \expandafter\endinput\fi\relax
 
 %%------------------
-\RequirePackage{expl3}
 %! Main part of luatexja-adjust
 \RequireLuaTeXjaSubmodule{adjust}
 
   \ifltj@japaram@adjust\ltjenableadjust\else\ltjdisableadjust\fi
 }
 
-\ExplSyntaxOn
-\cs_new:Nn \ltj_adjust_inittable: {
-  % To be filled...
-}
-\cs_new:Nn \ltj_adjust_appendtable:n {
-  % To be filled
-}
-
-\clist_new:N \l_ltj_adjust_priority
-\define@key[ltj]{japaram}{adjustpriority}{% COMMA LIST
-  \clist_set:Nx \l_ltj_adjust_priority {#1}
-  \ltj_adjust_inittable:
-  \clist_map_function:NN \l_ltj_adjust_priority \ltj_adjust_appendtable:n
-}
-
-\ExplSyntaxOff
-
+\ifltj@in@latex
+  \RequirePackage{expl3}
+  \ExplSyntaxOn
+  \cs_new:Nn \ltj_adjust_inittable: {
+    % To be filled...
+  }
+  \cs_new:Nn \ltj_adjust_appendtable:n {
+    % To be filled
+  }
+  \clist_new:N \l_ltj_adjust_priority
+  \define@key[ltj]{japaram}{adjustpriority}{% COMMA LIST
+    \clist_set:Nx \l_ltj_adjust_priority {#1}
+    \ltj_adjust_inittable:
+    \clist_map_function:NN \l_ltj_adjust_priority \ltj_adjust_appendtable:n
+  }
+  \ExplSyntaxOff
+\fi
 
 %%------------------ all done
 \ltj@adjust@AtEnd
index 885a649..efa8072 100644 (file)
@@ -3,7 +3,7 @@
 --
 luatexbase.provides_module({
   name = 'luatexja.adjust',
-  date = '2014/01/24',
+  date = '2014/01/26',
   description = 'Advanced line adjustment for LuaTeX-ja',
 })
 module('luatexja.adjust', package.seeall)
@@ -54,7 +54,10 @@ local round = tex.round
 local PACKED       = luatexja.icflag_table.PACKED
 local FROM_JFM     = luatexja.icflag_table.FROM_JFM
 local KANJI_SKIP   = luatexja.icflag_table.KANJI_SKIP
+local KANJI_SKIP_JFM = luatexja.icflag_table.KANJI_SKIP_JFM
 local XKANJI_SKIP  = luatexja.icflag_table.XKANJI_SKIP
+local XKANJI_SKIP_JFM  = luatexja.icflag_table.XKANJI_SKIP_JFM
+local PROCESSED_BEGIN_FLAG = luatexja.icflag_table.PROCESSED_BEGIN_FLAG
 
 local priority_table = {
    FROM_JFM + 2,
@@ -66,7 +69,6 @@ local priority_table = {
    KANJI_SKIP
 }
 
-local PROCESSED_BEGIN_FLAG = 32
 local function get_attr_icflag(p)
    return (has_attr(p, attr_icflag) or 0) % PROCESSED_BEGIN_FLAG
 end
@@ -88,7 +90,6 @@ local function get_stretched(q, go, gs)
 end
 
 local res = {}
-local is_skip_normal = {}
 local function get_total_stretched(p)
    local go, gf, gs 
       = getfield(p, 'glue_order'), getfield(p, 'glue_set'), getfield(p, 'glue_sign')
@@ -103,13 +104,18 @@ local function get_total_stretched(p)
         -- それはここでは望ましくないので,各 glue ごとに異なる spec を使う.
         -- (この仮定でメモリリークを起こしている!)
         -- JFM グルーはそれぞれ異なる glue_spec を用いているので,問題ない.
-        res[ic] = res[ic] + a
         if (ic == KANJI_SKIP or ic == XKANJI_SKIP) and getsubtype(q)==0 then
            local qs = getfield(q, 'spec')
-           if is_skip_normal[ic] and qs ~= spec_zero_glue then
+           if qs ~= spec_zero_glue then
+              local f = node_new(id_glue)
+              setfield(f, 'spec', qs)
               setfield(q, 'spec', node_copy(qs))
+              node_free(f)
            end
+        elseif ic == KANJI_SKIP_JFM  then ic = KANJI_SKIP
+        elseif ic == XKANJI_SKIP_JFM  then ic = XKANJI_SKIP
         end
+        res[ic] = res[ic] + a
       else 
         res[0]  = res[0]  + a
       end
@@ -138,7 +144,9 @@ local function set_stretch(p, after, before, ic, name)
          set_stretch_table[i] = nil
       end
       for q in node_traverse_id(id_glue, getlist(p)) do
-         if get_attr_icflag(q) == ic then
+        local f = get_attr_icflag(q)
+         if (f == ic) or ((ic ==KANJI_SKIP) and (f == KANJI_SKIP_JFM)) 
+          or ((ic ==XKANJI_SKIP) and (f == XKANJI_SKIP_JFM)) then
             local qs, do_flag = getfield(q, 'spec'), true
             for i=1,#set_stretch_table do 
                if set_stretch_table[i]==qs then do_flag = false end 
@@ -236,12 +244,12 @@ local function aw_step2(p, res, total, added_flag)
 end
 
 
-function adjust_width(head) 
+local ltjs_fast_get_stack_skip = ltjs.fast_get_stack_skip
+local function adjust_width(head) 
    if not head then return head end
-   is_skip_normal[KANJI_SKIP] = (ltjs.fast_get_stack_skip('kanjiskip').width ~= 1073741823)
-   is_skip_normal[XKANJI_SKIP] = (ltjs.fast_get_stack_skip('xkanjiskip').width ~= 1073741823)
    for p in node_traverse_id(id_hlist, to_direct(head)) do
-      local res = get_total_stretched(p)
+      local res = get_total_stretched(p) 
+        -- this is the same table as the table which is def'd in l. 92
       if res then
          -- 調整量の合計
          local total = 0
@@ -250,25 +258,26 @@ function adjust_width(head)
                total = total + v
             end
          end; total = round(total * res.glue_set)
-         local added_flag = aw_step1(p, res, total)
-         --print(total, res[0], res[KANJI_SKIP], res[FROM_JFM])
-         aw_step2(p, res, total, added_flag)
+         aw_step2(p, res, total, aw_step1(p, res, total))
       end
    end
    return to_node(head)
 end
 
-local is_reg = false
-function enable_cb()
-   if not is_reg then
-      luatexbase.add_to_callback('post_linebreak_filter', adjust_width, 'Adjust width', 100)
-      is_reg = true
+do
+   local is_reg = false
+   function enable_cb()
+      if not is_reg then
+        luatexbase.add_to_callback('post_linebreak_filter', 
+                                   adjust_width, 'Adjust width', 100)
+        is_reg = true
+      end
    end
-end
-function disable_cb()
-   if is_reg then
-      luatexbase.remove_from_callback('post_linebreak_filter', 'Adjust width')
-      is_reg = false
+   function disable_cb()
+      if is_reg then
+        luatexbase.remove_from_callback('post_linebreak_filter', 'Adjust width')
+        is_reg = false
+      end
    end
 end
 
index 30068a6..a6d2e28 100644 (file)
@@ -73,8 +73,6 @@ local ITALIC       = luatexja.icflag_table.ITALIC
 local PACKED       = luatexja.icflag_table.PACKED
 local KINSOKU      = luatexja.icflag_table.KINSOKU
 local FROM_JFM     = luatexja.icflag_table.FROM_JFM
-local KANJI_SKIP   = luatexja.icflag_table.KANJI_SKIP
-local XKANJI_SKIP  = luatexja.icflag_table.XKANJI_SKIP
 local PROCESSED    = luatexja.icflag_table.PROCESSED
 local IC_PROCESSED = luatexja.icflag_table.IC_PROCESSED
 local BOXBDD       = luatexja.icflag_table.BOXBDD
@@ -581,41 +579,45 @@ end
 
 -- get kanjiskip
 local get_kanjiskip
-
-local function get_kanjiskip_normal()
-   if Np.auto_kspc or Nq.auto_kspc then
-      return node_copy(kanji_skip)
-   else
-      local g = node_copy(zero_glue)
-      set_attr(g, attr_icflag, KANJI_SKIP)
-      return g
+local get_kanjiskip_normal, get_kanjiskip_jfm
+do
+   local KANJI_SKIP   = luatexja.icflag_table.KANJI_SKIP
+   local KANJI_SKIP_JFM   = luatexja.icflag_table.KANJI_SKIP_JFM
+   get_kanjiskip_normal = function ()
+      if Np.auto_kspc or Nq.auto_kspc then
+        return node_copy(kanji_skip)
+      else
+        local g = node_copy(zero_glue)
+        set_attr(g, attr_icflag, KANJI_SKIP)
+        return g
+      end
    end
-end
 
-local function get_kanjiskip_jfm()
-   local g
-   if Np.auto_kspc or Nq.auto_kspc then
-      g = node_new(id_glue); --copy_attr(g, Nq.nuc)
-      local gx = node_new(id_glue_spec);
-      setfield(gx, 'stretch_order', 0); setfield(gx, 'shrink_order', 0)
-      local pm, qm = Np.met, Nq.met
-      local bk = qm.kanjiskip or {0, 0, 0}
-      if (pm.char_type==qm.char_type) and (qm.var==pm.var) then
-        setfield(gx, 'width', bk[1])
-        setfield(gx, 'stretch', bk[2])
-        setfield(gx, 'shrink', bk[3])
+   get_kanjiskip_jfm = function ()
+      local g
+      if Np.auto_kspc or Nq.auto_kspc then
+        g = node_new(id_glue); --copy_attr(g, Nq.nuc)
+        local gx = node_new(id_glue_spec);
+        setfield(gx, 'stretch_order', 0); setfield(gx, 'shrink_order', 0)
+        local pm, qm = Np.met, Nq.met
+        local bk = qm.kanjiskip or {0, 0, 0}
+        if (pm.char_type==qm.char_type) and (qm.var==pm.var) then
+           setfield(gx, 'width', bk[1])
+           setfield(gx, 'stretch', bk[2])
+           setfield(gx, 'shrink', bk[3])
+        else
+           local ak = pm.kanjiskip or {0, 0, 0}
+           setfield(gx, 'width', round(diffmet_rule(bk[1], ak[1])))
+           setfield(gx, 'stretch', round(diffmet_rule(bk[2], ak[2])))
+           setfield(gx, 'shrink', -round(diffmet_rule(-bk[3], -ak[3])))
+        end
+        setfield(g, 'spec', gx)
       else
-         local ak = pm.kanjiskip or {0, 0, 0}
-        setfield(gx, 'width', round(diffmet_rule(bk[1], ak[1])))
-        setfield(gx, 'stretch', round(diffmet_rule(bk[2], ak[2])))
-        setfield(gx, 'shrink', -round(diffmet_rule(-bk[3], -ak[3])))
+        g =  node_copy(zero_glue)
       end
-      setfield(g, 'spec', gx)
-   else
-      g =  node_copy(zero_glue)
+      set_attr(g, attr_icflag, KANJI_SKIP_JFM)
+      return g
    end
-   set_attr(g, attr_icflag, KANJI_SKIP)
-   return g
 end
 
 local calc_ja_ja_aux
@@ -708,32 +710,37 @@ end
 
 -- get xkanjiskip
 local get_xkanjiskip
-local function get_xkanjiskip_normal(Nn)
-   if (Nq.xspc>=2) and (Np.xspc%2==1) and (Nq.auto_xspc or Np.auto_xspc) then
-      local f = node_copy(xkanji_skip)
-      return f
-   else
-      local g = node_copy(zero_glue)
-      set_attr(g, attr_icflag, XKANJI_SKIP)
-      return g
+local get_xkanjiskip_normal, get_xkanjiskip_jfm
+do
+   local XKANJI_SKIP   = luatexja.icflag_table.XKANJI_SKIP
+   local XKANJI_SKIP_JFM   = luatexja.icflag_table.XKANJI_SKIP_JFM
+   get_xkanjiskip_normal = function (Nn)
+      if (Nq.xspc>=2) and (Np.xspc%2==1) and (Nq.auto_xspc or Np.auto_xspc) then
+        local f = node_copy(xkanji_skip)
+        return f
+      else
+        local g = node_copy(zero_glue)
+        set_attr(g, attr_icflag, XKANJI_SKIP)
+        return g
+      end
    end
-end
-local function get_xkanjiskip_jfm(Nn)
-   local g
-   if (Nq.xspc>=2) and (Np.xspc%2==1) and (Nq.auto_xspc or Np.auto_xspc) then
-      g = node_new(id_glue)
-      local gx = node_new(id_glue_spec);
-      setfield(gx, 'stretch_order', 0); setfield(gx, 'shrink_order', 0)
-      local bk = Nn.met.xkanjiskip or {0, 0, 0}
-      setfield(gx, 'width', bk[1])
-      setfield(gx, 'stretch', bk[2])
-      setfield(gx, 'shrink', bk[3])
-      setfield(g, 'spec', gx)
-   else
-      g = node_copy(zero_glue)
+   get_xkanjiskip_jfm = function (Nn)
+      local g
+      if (Nq.xspc>=2) and (Np.xspc%2==1) and (Nq.auto_xspc or Np.auto_xspc) then
+        g = node_new(id_glue)
+        local gx = node_new(id_glue_spec);
+        setfield(gx, 'stretch_order', 0); setfield(gx, 'shrink_order', 0)
+        local bk = Nn.met.xkanjiskip or {0, 0, 0}
+        setfield(gx, 'width', bk[1])
+        setfield(gx, 'stretch', bk[2])
+        setfield(gx, 'shrink', bk[3])
+        setfield(g, 'spec', gx)
+      else
+        g = node_copy(zero_glue)
+      end
+      set_attr(g, attr_icflag, XKANJI_SKIP_JFM)
+      return g
    end
-   set_attr(g, attr_icflag, XKANJI_SKIP)
-   return g
 end
 
 -------------------- 隣接した「塊」間の処理
@@ -891,46 +898,49 @@ end
 
 -- initialize
 -- return value: (the initial cursor lp), (last node)
-local function init_var(mode)
-   -- 1073741823: max_dimen
-   Bp, widow_Bp, widow_Np = {}, {}, {first = nil}
-   table_current_stack = ltjs.table_current_stack
-
-   kanji_skip = node_new(id_glue)
-   setfield(kanji_skip, 'spec', skip_table_to_spec('kanjiskip'))
-   set_attr(kanji_skip, attr_icflag, KANJI_SKIP)
-   get_kanjiskip = (getfield(getfield(kanji_skip, 'spec'), 'width') == 1073741823)
-      and get_kanjiskip_jfm or get_kanjiskip_normal
-
-   xkanji_skip = node_new(id_glue)
-   setfield(xkanji_skip, 'spec', skip_table_to_spec('xkanjiskip'))
-   set_attr(xkanji_skip, attr_icflag, XKANJI_SKIP)
-   get_xkanjiskip = (getfield(getfield(xkanji_skip, 'spec'), 'width') == 1073741823)
-      and get_xkanjiskip_jfm or get_xkanjiskip_normal
-
-   Np = {
-      auto_kspc=nil, auto_xspc=nil, char=nil, class=nil, 
-      first=nil, id=nil, last=nil, met=nil, nuc=nil, 
-      post=nil, pre=nil, xspc=nil, 
-   }
-   Nq = {
-      auto_kspc=nil, auto_xspc=nil, char=nil, class=nil, 
-      first=nil, id=nil, last=nil, met=nil, nuc=nil, 
-      post=nil, pre=nil, xspc=nil, 
-   }
-   if mode then 
-      -- the current list is to be line-breaked:
-      -- hbox from \parindent is skipped.
-      local lp, par_indented, lpi, lps  = head, 'boxbdd', getid(head), getsubtype(head)
-      while lp and ((lpi==id_whatsit and lps~=sid_user) 
-                or ((lpi==id_hlist) and (lps==3))) do
-        if (lpi==id_hlist) and (lps==3) then par_indented = 'parbdd' end
-        lp=node_next(lp); lpi, lps = getid(lp), getsubtype(lp) end
-     return lp, par_indented
-     -- return lp, node_tail(head), par_indented
-   else 
-      -- the current list is the contents of a hbox:
-      return head, 'boxbdd'
+local init_var
+do
+   local KANJI_SKIP   = luatexja.icflag_table.KANJI_SKIP
+   local XKANJI_SKIP   = luatexja.icflag_table.XKANJI_SKIP
+   init_var = function (mode)
+      -- 1073741823: max_dimen
+      Bp, widow_Bp, widow_Np = {}, {}, {first = nil}
+      table_current_stack = ltjs.table_current_stack
+      
+      kanji_skip = node_new(id_glue)
+      setfield(kanji_skip, 'spec', skip_table_to_spec('kanjiskip'))
+      set_attr(kanji_skip, attr_icflag, KANJI_SKIP)
+      get_kanjiskip = (getfield(getfield(kanji_skip, 'spec'), 'width') == 1073741823)
+        and get_kanjiskip_jfm or get_kanjiskip_normal
+      
+      xkanji_skip = node_new(id_glue)
+      setfield(xkanji_skip, 'spec', skip_table_to_spec('xkanjiskip'))
+      set_attr(xkanji_skip, attr_icflag, XKANJI_SKIP)
+      get_xkanjiskip = (getfield(getfield(xkanji_skip, 'spec'), 'width') == 1073741823)
+        and get_xkanjiskip_jfm or get_xkanjiskip_normal
+      
+      Np = {
+        auto_kspc=nil, auto_xspc=nil, char=nil, class=nil, 
+        first=nil, id=nil, last=nil, met=nil, nuc=nil, 
+        post=nil, pre=nil, xspc=nil, 
+      }
+      Nq = {
+        auto_kspc=nil, auto_xspc=nil, char=nil, class=nil, 
+        first=nil, id=nil, last=nil, met=nil, nuc=nil, 
+        post=nil, pre=nil, xspc=nil, 
+      }
+      if mode then 
+        -- the current list is to be line-breaked:
+        -- hbox from \parindent is skipped.
+        local lp, par_indented, lpi, lps  = head, 'boxbdd', getid(head), getsubtype(head)
+        while lp and ((lpi==id_whatsit and lps~=sid_user) 
+                      or ((lpi==id_hlist) and (lps==3))) do
+           if (lpi==id_hlist) and (lps==3) then par_indented = 'parbdd' end
+           lp=node_next(lp); lpi, lps = getid(lp), getsubtype(lp) end
+        return lp, par_indented
+      else 
+        return head, 'boxbdd'
+      end
    end
 end
 
index 9e0dd8b..1f818ee 100644 (file)
@@ -26,14 +26,16 @@ icflag_table.ITALIC       = 1
 icflag_table.PACKED       = 2
 icflag_table.KINSOKU      = 3
 icflag_table.FROM_JFM     = 6
--- FROM_JFM: 4, 5, 6, 7, 8 →優先度高
+-- FROM_JFM: 4, 5, 6, 7, 8 →優先度高(伸びやすく,縮みやすい)
 -- 6 が標準
 icflag_table.KANJI_SKIP   = 9
-icflag_table.XKANJI_SKIP  = 10
-icflag_table.PROCESSED    = 11
-icflag_table.IC_PROCESSED = 12
+icflag_table.KANJI_SKIP_JFM   = 10
+icflag_table.XKANJI_SKIP  = 11
+icflag_table.XKANJI_SKIP_JFM  = 12
+icflag_table.PROCESSED    = 13
+icflag_table.IC_PROCESSED = 14
 icflag_table.BOXBDD       = 15
-icflag_table.PROCESSED_BEGIN_FLAG = 32
+icflag_table.PROCESSED_BEGIN_FLAG = 128
 
 local stack_table_index = {}
 luatexja.stack_table_index = stack_table_index
@@ -349,8 +351,12 @@ local function debug_show_node_X(p,print_fn)
          s = s .. ' (from JFM: priority ' .. get_attr_icflag(p)-icflag_table.FROM_JFM .. ')'
       elseif get_attr_icflag(p)==icflag_table.KANJI_SKIP then
         s = s .. ' (kanjiskip)'
+      elseif get_attr_icflag(p)==icflag_table.KANJI_SKIP_JFM then
+        s = s .. ' (kanjiskip, JFM specified)'
       elseif get_attr_icflag(p)==icflag_table.XKANJI_SKIP then
         s = s .. ' (xkanjiskip)'
+      elseif get_attr_icflag(p)==icflag_table.XKANJI_SKIP_JFM then
+        s = s .. ' (xkanjiskip, JFM specified)'
       end
       print_fn(s)
    elseif pt == 'kern' then