OSDN Git Service

Moved Lua codes of test17-priority.tex into ltj-adjust.lua.
authorHironori Kitagawa <h_kitagawa2001@yahoo.co.jp>
Thu, 27 Sep 2012 14:26:24 +0000 (23:26 +0900)
committerHironori Kitagawa <h_kitagawa2001@yahoo.co.jp>
Thu, 27 Sep 2012 14:26:24 +0000 (23:26 +0900)
src/ltj-adjust.lua [new file with mode: 0644]
test/test17-priority.pdf
test/test17-priority.tex

diff --git a/src/ltj-adjust.lua b/src/ltj-adjust.lua
new file mode 100644 (file)
index 0000000..d2ba3aa
--- /dev/null
@@ -0,0 +1,138 @@
+--
+-- luatexja/otf.lua
+--
+luatexbase.provides_module({
+  name = 'luatexja.adjust',
+  date = '2012/09/27',
+  version = '0.1',
+  description = 'Advanced line adjustment for LuaTeX-ja',
+})
+module('luatexja.adjust', package.seeall)
+
+local id_hlist = node.id('hlist')
+local id_glue  = node.id('glue')
+local id_glue_spec = node.id('glue_spec')
+local attr_icflag = luatexbase.attributes['ltj@icflag']
+
+local PACKED = 2
+local FROM_JFM = 6
+local KANJI_SKIP = 9
+local XKANJI_SKIP = 10
+
+local priority_table = {
+   XKANJI_SKIP,
+   FROM_JFM + 2,
+   FROM_JFM + 1,
+   FROM_JFM,
+   FROM_JFM - 1,
+   FROM_JFM - 2,
+   KANJI_SKIP
+}
+
+local PROCESSED_BEGIN_FLAG = 32
+local function get_attr_icflag(p)
+   return (node.has_attribute(p, attr_icflag) or 0) % PROCESSED_BEGIN_FLAG
+end
+
+-- box 内で伸縮された glue の合計値を計算
+
+local function get_stretched(q, go, gs)
+   local qs = q.spec
+   if not qs.writable then return 0 end
+   if gs == 1 then -- stretching
+      if qs.stretch_order == go then return qs.stretch end
+   else -- shrinking
+      if qs.shrink_order == go then return qs.shrink end
+   end
+end
+
+local function get_total_stretched(p)
+   local go, gf, gs = p.glue_order, p.glue_set, p.glue_sign
+   local res = {
+      [0] = 0,
+      glue_set = gf, name = (gs==1) and 'stretch' or 'shrink'
+   }
+   for i=1,#priority_table do res[priority_table[i]]=0 end
+   if go ~= 0 then return nil end
+   if gs ~= 1 and gs ~= 2 then return res end
+   for q in node.traverse_id(id_glue, p.head) do
+      local a, ic = get_stretched(q, go, gs), get_attr_icflag(q)
+      --print(ic)
+      if   type(res[ic]) == 'number' then res[ic] = res[ic] + a
+      else                                res[0]  = res[0]  + a
+      end
+   end
+   return res
+end
+
+local function clear_stretch(p, ic, name)
+   --print('clear ' .. ic)
+   for q in node.traverse_id(id_glue, p.head) do
+      if get_attr_icflag(q) == ic then
+         local qs = q.spec
+         if qs.writable then
+            qs[name..'_order'], qs[name] = 0, 0
+         end
+      end
+   end
+end
+
+local function set_stretch(p, after, before, ic, name)
+   if before > 0 then
+      --print (ic, before, after)
+      local ratio = after/before
+      for q in node.traverse_id(id_glue, p.head) do
+         if get_attr_icflag(q) == ic then
+            local qs = q.spec
+            if qs.writable and qs[name..'_order'] == 0 then
+               qs[name] = qs[name]*ratio
+            end
+         end
+      end
+   end
+end
+
+
+function adjust_width(head) 
+   if not head then return head end
+   for p in node.traverse_id(id_hlist, head) do
+      local res = get_total_stretched(p)
+      --print(table.serialize(res))
+      if res then
+         -- 調整量の合計
+         local total = 0
+         for i,v in pairs(res) do 
+            if type(i)=='number' then
+               total = total + v
+            end
+         end; total = tex.round(total * res.glue_set)
+         if total <= res[0] then -- 和文処理グルー以外で足りる
+            for _,v in pairs(priority_table) do clear_stretch(p, v, res.name) end
+            local f = node.hpack(p.head, p.width, 'exactly')
+            f.head, p.glue_set, p.glue_sign, p.glue_order 
+               = nil, f.glue_set, f.glue_sign, f.glue_order
+            node.free(f)
+         else
+            total = total - res[0]
+            for i = 1, #priority_table do
+               local v = priority_table[i]
+               if total <= res[v] then
+                  for j = i+1,#priority_table do
+                     clear_stretch(p, priority_table[j], res.name)
+                  end
+                  set_stretch(p, total, res[v], v, res.name)
+                  local f = node.hpack(p.head, p.width, 'exactly')
+                  f.head, p.glue_set, p.glue_sign, p.glue_order 
+                     = nil, f.glue_set, f.glue_sign, f.glue_order
+                  node.free(f)
+                  --print(p.glue_set, p.glue_sign, p.glue_order)
+                  return head
+               end
+               total = total - res[v]
+            end
+         end
+      end
+   end
+   return head
+end
+
index ed8ecc0..06c5c81 100644 (file)
Binary files a/test/test17-priority.pdf and b/test/test17-priority.pdf differ
index 077b7c5..f92e41b 100644 (file)
 %#!lualatex
 
-%% 行末の句読点の位置によって,全角取りか半角取りかを自動的に調整する
-%% 仕様:全調整量が二分以上なら,全角取りにする
 \documentclass{article}
 \usepackage{luatexja,luacode,xcolor}
-\begin{luacode}
-local id_hlist = node.id('hlist')
-local id_glue  = node.id('glue')
-local id_glue_spec = node.id('glue_spec')
-local attr_icflag = luatexbase.attributes['ltj@icflag']
-local PACKED = 2
-local PROCESSED_BEGIN_FLAG = 32
-local FROM_JFM = 6
-local KANJI_SKIP = 9
-local XKANJI_SKIP = 10
-
-local function get_attr_icflag(p)
-   return (node.has_attribute(p, attr_icflag) or 0) % PROCESSED_BEGIN_FLAG
-end
-
--- box 内で伸縮された glue の合計値を計算
-
-local function get_stretched(q, go, gs)
-  local qs = q.spec
-  if not qs.writable then return 0 end
-  if gs == 1 then -- stretching
-    if qs.stretch_order == go then return qs.stretch end
-  else -- shrinking
-    if qs.shrink_order == go then return qs.shrink end
-  end
-end
-
-local function get_total_stretched(p)
-  local go, gf, gs = p.glue_order, p.glue_set, p.glue_sign
-  local res = {
-    other = 0, xkanji = 0, jfm = 0, kanji = 0, 
-    glue_set = gf, glue_sign = gs
-  }
-  if go ~= 0 then return nil end
-  if gs ~= 1 and gs ~= 2 then return res end
-  for q in node.traverse_id(id_glue, p.head) do
-    local a, ic = get_stretched(q, go, gs), get_attr_icflag(q)
-    if     ic == KANJI_SKIP  then res.kanji  = res.kanji + a
-    elseif ic == XKANJI_SKIP then res.xkanji = res.xkanji + a
-    elseif ic == FROM_JFM    then res.jfm    = res.jfm + a
-    else                          res.other  = res.other + a
-    end
-  end
-  return res
-end
-
-local function clear_stretch(p, ic)
-  for q in node.traverse_id(id_glue, p.head) do
-    if get_attr_icflag(q) == ic then
-      local qs = q.spec
-      if qs.writable then
-        qs.stretch_order, qs.shrink_order, qs.stretch, qs.shrink = 0, 0, 0, 0
-      end
-    end
-  end
-end
-
-local function set_stretch(p, after, before, ic)
-  if before > 0 then
-    print (ic, before, after)
-    local ratio = after/before
-    for q in node.traverse_id(id_glue, p.head) do
-      if get_attr_icflag(q) == ic then
-        local qs = q.spec
-        if qs.writable then
-          qs.stretch, qs.shrink = qs.stretch*ratio, qs.shrink*ratio
-        end
-      end
-    end    
-  end
-end
-
-function adjust_width(head) 
-  if not head then return head end
-  for p in node.traverse_id(id_hlist, head) do
-    local res = get_total_stretched(p)
-    if res then
-      -- 調整量の合計
-      local total = tex.round((res.other + res.xkanji + res.jfm + res.kanji) * res.glue_set)
-      print('before: ', p.glue_set, p.glue_sign, p.glue_order )
-      print(total, res.other, res.xkanji, res.jfm, res.kanji)
-      if total <= res.other then -- 和文処理グルー以外で足りる
-        clear_stretch(p, KANJI_SKIP)
-        clear_stretch(p, XKANJI_SKIP)
-        clear_stretch(p, FROM_JFM)
-        local f = node.hpack(p.head, p.width, 'exactly')
-        f.head, p.glue_set, p.glue_sign, p.glue_order 
-           = nil, f.glue_set, f.glue_sign, f.glue_order
-        node.free(f)
-      else
-        total = total - res.other
-        if total <= res.jfm then -- JFMグルーだけで良い
-          clear_stretch(p, KANJI_SKIP)
-          clear_stretch(p, XKANJI_SKIP)
-          set_stretch(p, total,res.jfm, FROM_JFM)
-          local f = node.hpack(p.head, p.width, 'exactly')
-          f.head, p.glue_set, p.glue_sign, p.glue_order 
-             = nil, f.glue_set, f.glue_sign, f.glue_order
-          node.free(f)
-        else
-          total = total - res.jfm
-          if total <= res.xkanji then -- xkanjiskip まで
-            clear_stretch(p, KANJI_SKIP)
-            set_stretch(p, total,res.xkanji, XKANJI_SKIP)
-            local f = node.hpack(p.head, p.width, 'exactly')
-            f.head, p.glue_set, p.glue_sign, p.glue_order 
-               = nil, f.glue_set, f.glue_sign, f.glue_order
-            node.free(f)
-          else
-            total = total - res.xkanji
-            if total <= res.kanji then -- kanjiskip まで
-              set_stretch(p, total,res.kanji, KANJI_SKIP)
-              local f = node.hpack(p.head, p.width, 'exactly')
-              f.head, p.glue_set, p.glue_sign, p.glue_order 
-                 = nil, f.glue_set, f.glue_sign, f.glue_order
-              node.free(f)
-            else
-              -- glue_set > 1 なので,どうしようもない
-            end
-          end
-        end
-      end
-    print('after:  ', p.glue_set, p.glue_sign, p.glue_order )
-    end
-  end
-  return head
-end
-
-
-\end{luacode}
-
-\def\sq{\hbox to 1\zw{\hss\fboxsep=-.5\fboxrule\fbox{ }\hss}}
-\def\sb{\hbox to 1\zw{\hss\fboxsep=-.5\fboxrule\fbox{■}\hss}}
+\RequireLuaTeXjaSubmodule{adjust}
+
+\def\sq{%
+  \hbox to 1\zw{\hss\fboxsep=-.5\fboxrule\fbox{%
+   \hskip\dimexpr-.5\zw-.2pt\vrule width.4pt height.08\zw depth.12\zw%
+  \hskip\dimexpr.5\zw-.2pt\relax}\hss}}
+\def\sb{\hbox to 1\zw{\hss\fboxsep=-.5\fboxrule\fbox{%
+  ■\hskip\dimexpr-.5\zw-.2pt\vrule width.4pt height.08\zw depth.12\zw%
+  \hskip\dimexpr.5\zw-.2pt\relax}\hss}}
 \newbox\gridbox
 \setbox\gridbox=\hbox to 20\zw{\sq\sq\sq\sq\sb\sq\sq\sq\sq\sb\sq\sq\sq\sq\sb\sq\sq\sq\sq\sb}
 \def\outbox#1{%
@@ -145,7 +19,7 @@ end
 }
 
 \def\DisableCB{\directlua{luatexbase.remove_from_callback('post_linebreak_filter', 'Adjust width')}}
-\def\EnableCB{\directlua{luatexbase.add_to_callback('post_linebreak_filter', adjust_width, 'Adjust width', 100)}}
+\def\EnableCB{\directlua{luatexbase.add_to_callback('post_linebreak_filter', luatexja.adjust.adjust_width, 'Adjust width', 100)}}
 
 \long\def\testbox#1{%
   \EnableCB\setbox0=\vbox{\hsize=20\zw\parfillskip0pt#1}\outbox{ON}\par
@@ -156,11 +30,12 @@ end
 \begin{document}
 {\tt kanjiskip: \ltjgetparameter{kanjiskip}
 
-\ltjsetparameter{xkanjiskip=.25\zw plus .25\zw minus -.125\zw}
+\ltjsetparameter{xkanjiskip=.25\zw plus .25\zw minus .125\zw}
 xkanjiskip: \ltjgetparameter{xkanjiskip}}
 
 \testbox{%
-あいうえおかきくけこさしすせそたちつてと
+◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆
+%あいうえおかきくけこさしすせそたちつてと
 }
 
 \testbox{%
@@ -183,4 +58,10 @@ xkanjiskip: \ltjgetparameter{xkanjiskip}}
 \testbox{%
 日本では\pTeX,p\LaTeX がよく使われている。
 }
+
+中点類の空き詰めは括弧類より優先
+
+\testbox{%
+あいうえおかきくけ・こさしすせそたち「「あ
+}
 \end{document}
\ No newline at end of file