texlive[76166] Master/texmf-dist: luatexko (27aug25)

commits+karl at tug.org commits+karl at tug.org
Wed Aug 27 22:13:36 CEST 2025


Revision: 76166
          https://tug.org/svn/texlive?view=revision&revision=76166
Author:   karl
Date:     2025-08-27 22:13:36 +0200 (Wed, 27 Aug 2025)
Log Message:
-----------
luatexko (27aug25)

Modified Paths:
--------------
    trunk/Master/texmf-dist/doc/luatex/luatexko/ChangeLog
    trunk/Master/texmf-dist/doc/luatex/luatexko/README
    trunk/Master/texmf-dist/doc/luatex/luatexko/luatexko-doc.pdf
    trunk/Master/texmf-dist/doc/luatex/luatexko/luatexko-doc.tex
    trunk/Master/texmf-dist/tex/luatex/luatexko/luatexko.lua
    trunk/Master/texmf-dist/tex/luatex/luatexko/luatexko.sty

Modified: trunk/Master/texmf-dist/doc/luatex/luatexko/ChangeLog
===================================================================
--- trunk/Master/texmf-dist/doc/luatex/luatexko/ChangeLog	2025-08-27 20:13:27 UTC (rev 76165)
+++ trunk/Master/texmf-dist/doc/luatex/luatexko/ChangeLog	2025-08-27 20:13:36 UTC (rev 76166)
@@ -1,3 +1,14 @@
+2025-08-27	Dohyun Kim <nomosnomos at gmail com>
+
+	Version 4.5
+
+	* luatexko.lua:
+	- new function cjk_punctuation_spacing for classic mode
+	- hbox is sort of hanja character in linebreak process.
+
+	* luatexko.sty:
+	- remove blocking glues inserted by pxrubrica
+
 2025-08-24	Dohyun Kim <nomosnomos at gmail com>
 
 	Version 4.4

Modified: trunk/Master/texmf-dist/doc/luatex/luatexko/README
===================================================================
--- trunk/Master/texmf-dist/doc/luatex/luatexko/README	2025-08-27 20:13:27 UTC (rev 76165)
+++ trunk/Master/texmf-dist/doc/luatex/luatexko/README	2025-08-27 20:13:36 UTC (rev 76166)
@@ -1,4 +1,4 @@
-LuaTeX-ko Package version 4.4 (2025/08/24)
+LuaTeX-ko Package version 4.5 (2025/08/27)
 ===========================================
 
 This is a Lua(La)TeX macro package that supports typesetting Korean

Modified: trunk/Master/texmf-dist/doc/luatex/luatexko/luatexko-doc.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/luatex/luatexko/luatexko-doc.tex
===================================================================
--- trunk/Master/texmf-dist/doc/luatex/luatexko/luatexko-doc.tex	2025-08-27 20:13:27 UTC (rev 76165)
+++ trunk/Master/texmf-dist/doc/luatex/luatexko/luatexko-doc.tex	2025-08-27 20:13:36 UTC (rev 76166)
@@ -154,7 +154,7 @@
 \author{\normalsize Dohyun Kim |<nomosnomos at gmail com>| \and
         \normalsize Soojin Nam |<jsunam at gmail com>| \and
         \normalsize <\url{http://github.com/dohyunkim/luatexko}>}
-\date{Version 4.4\quad 2025/08/24}
+\date{Version 4.5\quad 2025/08/27}
 \maketitle
 
 \begin{quote}

Modified: trunk/Master/texmf-dist/tex/luatex/luatexko/luatexko.lua
===================================================================
--- trunk/Master/texmf-dist/tex/luatex/luatexko/luatexko.lua	2025-08-27 20:13:27 UTC (rev 76165)
+++ trunk/Master/texmf-dist/tex/luatex/luatexko/luatexko.lua	2025-08-27 20:13:36 UTC (rev 76166)
@@ -13,8 +13,8 @@
 
 luatexbase.provides_module {
   name        = 'luatexko',
-  date        = '2025/08/24',
-  version     = '4.4',
+  date        = '2025/08/27',
+  version     = '4.5',
   description = 'typesetting Korean with LuaTeX',
   author      = 'Dohyun Kim, Soojin Nam',
   license     = 'LPPL v1.3+',
@@ -113,6 +113,7 @@
 local rubyattr         = attributes.luatexkorubyattr
 local hangulbyhangulattr = attributes.luatexkohangulbyhangulattr
 local hanjabyhanjaattr   = attributes.luatexkohanjabyhanjaattr
+local inhibitglueattr  = attributes.luatexkoinhibitglueattr
 
 local unicodeattr = new_attribute"luatexkounicodeattr"
 
@@ -811,13 +812,10 @@
 
 local function is_blocking_node (curr)
   local id, subtype = curr.id, curr.subtype
-  if id == glueid and curr.width == 0 and curr.stretch == 0 and curr.shrink == 0 then
-    return false -- for pxrubrica
-  end
   return allowbreak_false_nodes[id] or id == kernid and subtype == userkern
 end
 
-local function hbox_char_font (box, init, glyfonly) -- ignore glyfonly
+local function hbox_char_font (box, init)
   local mynext = init and getnext  or getprev
   local curr   = init and box.list or nodeslide(box.list)
   while curr do
@@ -828,7 +826,7 @@
         return c, curr.font
       end
     elseif curr.list then
-      return hbox_char_font(curr, init, glyfonly)
+      return hbox_char_font(curr, init)
     end
     curr = mynext(curr)
   end
@@ -898,6 +896,57 @@
   return head, cc, ccl, fid
 end
 
+local function process_cjk_punctuation_spacing (head, par)
+  local pcl, pc, pf, old = 0, 0x4E00, false
+  local curr = head
+  if par then
+    while curr do
+      if curr.id == localparid or curr.id == hlistid and curr.subtype == indentbox then
+      else
+        break
+      end
+      curr = getnext(curr)
+    end
+    if curr.char and charclass[curr.char] == 1 then -- 1 is always 1
+      pc = false
+    end
+  end
+  while curr do
+    local id = curr.id
+    if id == glyphid and curr.lang ~= nohyphen then
+      local cc = curr.char
+      local cf = charclass[cc] == 0 and pf or curr.font
+      old = has_attribute(curr, classicattr)
+      local ccl = get_char_class(cc, old)
+      if old and intercharclass[pcl][ccl] then
+        head = maybe_linebreak(head, curr, pc, pcl, cc, old, cf, par)
+      end
+      pcl, pc, pf = ccl, cc, curr.font
+    elseif id == glueid and has_attribute(curr, inhibitglueattr) then
+      pcl, pc, pf = 0, false, false
+    else
+      if pf and (not par or node.length(curr) > 2) then -- penalty, parfillskip
+        old = has_attribute(curr, classicattr)
+        if old and intercharclass[pcl][0] then
+          head = maybe_linebreak(head, curr, pc, pcl, 0x4E00, old, pf, par)
+        end
+      end
+      pcl, pc, pf = 0, 0x4E00, false
+    end
+    curr = getnext(curr)
+  end
+  if not par and pf and old then
+    local ict = intercharclass[pcl][0]
+    if ict then
+      local gl = nodenew(glueid)
+      local en = fontoptions.en_size[pf]
+      setglue(gl, en * ict[1], nil, en * ict[2])
+      insert_after(head, nodeslide(head), gl)
+    end
+  end
+  return head
+end
+
 local function process_linebreak (head, par)
   local curr, pc, pcl, pf = head, false, 0, false
   while curr do
@@ -906,17 +955,18 @@
       local c = has_attribute(curr, unicodeattr) or curr.char
       if c and not is_combining(curr.char) then -- we are in pre-shaping stage
         local old = has_attribute(curr, classicattr)
-        head, pc, pcl, pf = maybe_linebreak(head, curr, pc, pcl, c, old, curr.font, par)
+        local f = is_noncjk_char(c) and pf or curr.font
+        head, pc, pcl, pf = maybe_linebreak(head, curr, pc, pcl, c, old, f, par)
       end
 
     elseif id == hlistid and curr.list then
-      local old = has_attribute(curr, classicattr)
-      local c, f = hbox_char_font(curr, true)
-      if c and f then
-        head = maybe_linebreak(head, curr, pc, pcl, c, old, pf or f, par)
+      if pf then
+        local old = has_attribute(curr, classicattr)
+        head = maybe_linebreak(head, curr, pc, pcl, 0x4E00, old, pf, par)
+      else
+        _, pf = hbox_char_font(curr)
       end
-      pc, pf = hbox_char_font(curr)
-      pcl = pc and get_char_class(pc, old) or 0
+      pc, pcl = 0x4E00, 0
 
     elseif id == whatsitid and curr.mode == directmode then
       local glyf, c, fin = get_actualtext(curr)
@@ -927,11 +977,11 @@
       end
 
     elseif id == mathid then
-      pc, pcl, curr, pf = 0x30, 0, end_of_math(curr), false
+      pc, pcl, curr = 0x30, 0, end_of_math(curr)
     elseif id == dirid then
-      pc, pcl, pf = curr.dir:sub(1,1) == "-" and 0x30, 0, false -- pop dir
+      pc, pcl = curr.dir:sub(1,1) == "-" and 0x30, 0 -- pop dir
     elseif is_blocking_node(curr) then
-      pc, pcl, pf = false, 0, false
+      pc, pcl = false, 0
     end
     curr = getnext(curr)
   end
@@ -967,14 +1017,6 @@
         end
       end
 
-    elseif id == hlistid and curr.list then
-      local c, f = hbox_char_font(curr, true)
-      if c and f then
-        head = do_interhangul_option(head, curr, pc, c, pf or f, par)
-      end
-      c, pf = hbox_char_font(curr)
-      pc = c and is_hangul_jamo(c) and 1 or 0
-
     elseif id == whatsitid and curr.mode == directmode then
       local glyf, c = get_actualtext(curr)
       if c and glyf then
@@ -996,20 +1038,18 @@
   local cc = is_cjk_char(c) and 1 or is_noncjk_char(c) and 2 or 0
   local old = has_attribute(curr, classicattr)
   local ccl = get_char_class(c, old)
+  local f = cc == 1 and cf or pf
 
   if cc*pc == 2 and curr.lang ~= nohyphen then
     local brb = cc == 2 or breakable_before[c] -- numletter != br_before
     if brb then
-      local f = cc == 1 and cf or pf
-      local dim = fontoptions.interlatincjk[f]
-      if dim then
+      local dimc = fontoptions.interlatincjk[cf] or 0
+      local dimp = fontoptions.interlatincjk[pf] or 0
+      local dim  = mathmax(dimc, dimp)
+      if dim ~= 0 then
         local ict = old and intercharclass[pcl][ccl] -- under classic env. only
         if ict then
           dim = fontoptions.intercharacter[f] or 0
-        elseif f == cf then
-          -- in case of Latin + pxrubrica ruby
-          local dim2 = fontoptions.en_size[pf]/fontoptions.en_size[f] * dim
-          if dim2 > dim then dim = dim2 end
         end
         head = insert_glue_before(head, curr, par, true, brb, old, ict, dim, f)
       end
@@ -1016,12 +1056,21 @@
     end
   end
 
-  return head, cc, cf, ccl
+  return head, cc, f, ccl
 end
 
 local function process_interlatincjk (head, par)
-  local curr, pc, pf, pcl = head, 0, 0, 0
+  local curr, pc, pf, pcl = head, 0, false, 0
   while curr do
+    if curr.id == glyphid and is_cjk_char(curr.char) then
+      pf = curr.font
+      break
+    end
+    curr = getnext(curr)
+  end
+
+  curr = head
+  while curr do
     local id = curr.id
     if id == glyphid then
       local c = has_attribute(curr, unicodeattr) or curr.char
@@ -1031,18 +1080,10 @@
       end
 
     elseif id == hlistid and curr.list then
-      local c, f = hbox_char_font(curr, true)
-      if c and f then
-        head = do_interlatincjk_option(head, curr, pc, pf, pcl, c, f, par)
-      end
-      c, f = hbox_char_font(curr)
-      if c and breakable_after[c] then
-        pc = is_cjk_char(c) and 1 or is_noncjk_char(c) and 2 or 0
-      else
-        pc = 0
-      end
-      pcl = c and get_char_class(c, has_attribute(curr, classicattr)) or 0
-      pf  = f or 0
+      local _, f = hbox_char_font(curr, true)
+      head = do_interlatincjk_option(head, curr, pc, pf, pcl, 0x4E00, pf or f, par)
+      _, f = hbox_char_font(curr)
+      pc, pcl, pf = 1, 0, pf or f
 
     elseif id == whatsitid and curr.mode == directmode then
       local glyf, c = get_actualtext(curr)
@@ -1055,18 +1096,19 @@
       if pc == 1 then
         head = do_interlatincjk_option(head, curr, pc, pf, pcl, 0x30, pf, par)
       end
-      pc, pf, pcl = 2, 0, 0
+      pc, pcl = 2, 0
       curr = end_of_math(curr)
 
     elseif id == dirid then
       if pc == 1 and curr.dir:sub(1,1) == "+" then
         head = do_interlatincjk_option(head, curr, pc, pf, pcl, 0x30, pf, par)
-        pc, pf, pcl = 0, 0, 0
       end
+      pc, pcl = 0, 0
 
     elseif is_blocking_node(curr) then
-      pc, pf, pcl = 0, 0, 0
+      pc, pcl = 0, 0
     end
+
     curr = getnext(curr)
   end
   return head
@@ -1127,7 +1169,6 @@
     local id = curr.id
     if id == glueid then
       if curr.subtype == spaceskip and has_attribute(curr, classicattr) then
-
         for k, v in pairs{ p = getprev(curr), n = getnext(curr) } do
           local ok
           while v do
@@ -1433,7 +1474,7 @@
             if shift ~= 0 then
               local list = box.list
               local k = nodenew(kernid)
-              k.kern = shift
+              k.kern, k.subtype = shift, userkern
               box.list = insert_before(list, list, k)
             end
 
@@ -1667,7 +1708,7 @@
           if side ~= 0 then
             local list = ruby.list
             local k = nodenew(kernid)
-            k.kern = side
+            k.kern, k.subtype = side, userkern
             ruby.list = insert_before(list, list, k)
           end
           ruby.width = 0
@@ -2253,6 +2294,7 @@
            or gc == "insert"
            or gc == "vcenter"
   h = call_callback("luatexko_prelinebreak_first", h, par)
+  h = process_cjk_punctuation_spacing(h, par)
   h = call_callback("luatexko_prelinebreak_second", h, par)
   return process_linebreak(h, par)
 end, "luatexko.pre_shaping_filter")

Modified: trunk/Master/texmf-dist/tex/luatex/luatexko/luatexko.sty
===================================================================
--- trunk/Master/texmf-dist/tex/luatex/luatexko/luatexko.sty	2025-08-27 20:13:27 UTC (rev 76165)
+++ trunk/Master/texmf-dist/tex/luatex/luatexko/luatexko.sty	2025-08-27 20:13:36 UTC (rev 76166)
@@ -14,7 +14,7 @@
 \ifdefined\luatexkohangulfontattr \endinput\fi
 \ifdefined\ProvidesPackage
   \NeedsTeXFormat{LaTeX2e}[2025/06/01]
-  \ProvidesPackage{luatexko}[2025/08/24 v4.4 typesetting Korean with LuaTeX]
+  \ProvidesPackage{luatexko}[2025/08/27 v4.5 typesetting Korean with LuaTeX]
   \RequirePackage{luatexbase}
   \RequirePackage{fontspec}[2020/02/03]
   \let\luatexkoselectfont\selectfont
@@ -35,6 +35,7 @@
 \newattribute\luatexkorubyattr \chardef\luatexkorubyalloc\allocationnumber
 \newattribute\luatexkohangulbyhangulattr
 \newattribute\luatexkohanjabyhanjaattr
+\newattribute\luatexkoinhibitglueattr
 \directlua{ require"luatexko" }
 % classics
 % 0: horizontal KO, JP
@@ -69,7 +70,7 @@
   \fi
   }
 \protected\def\typesetmodern{\unsetattribute\luatexkoclassicattr}
-\protected\def\inhibitglue{\hskip\z at skip}
+\protected\def\inhibitglue{\begingroup\luatexkoinhibitglueattr\@ne\hskip\z at skip\endgroup}
 \protected\def\japanese{% 0, 5
   \chardef\luatexkolangCJK=\@ne
   \ifcase\luatexkoclassicattr
@@ -995,7 +996,24 @@
     \def\는{는}\def\은{은}\def\을{을}\def\를{를}\def\와{와}\def\과{과}%
     \def\가{가}\def\이{이}\def\라{라}\def\으{으}\def\로{로}%
     \def\hellipsis{...}}}
-\AddToHook{package/pxrubrica/after}{\let\ruby\jruby}
+\AddToHook{package/pxrubrica/after}{\let\ruby\jruby
+  \AddToHook{cmd/pxrr at jprologue/before}{\begingroup\luatexkorubyattr\m at ne}
+  \AddToHook{cmd/pxrr at jepilogue/after}{\endgroup}
+  \directlua{
+    luatexbase.add_to_callback("pre_shaping_filter", function(head)
+      local tofree = {}
+      for n in node.traverse_id(node.id"glue", head) do
+        if n.width == 0 and n.stretch == 0 and n.shrink == 0
+          and node.has_attribute(n, \the\luatexkorubyalloc, -1) then
+          head = node.remove(head, n)
+          table.insert(tofree, n)
+        end
+      end
+      for _,v in ipairs(tofree) do node.free(v) end
+      return head
+    end, "luatexko.pxrubrica.removeglues", 1)
+  }
+}
 % misc
 \RequirePackage{kolabels-utf}
 \protected\def\hellipsis{\char"2026\char"2026 }



More information about the tex-live-commits mailing list.