texlive[67604] Master/texmf-dist: spacekern (10jul23)

commits+karl at tug.org commits+karl at tug.org
Mon Jul 10 21:33:56 CEST 2023


Revision: 67604
          http://tug.org/svn/texlive?view=revision&revision=67604
Author:   karl
Date:     2023-07-10 21:33:56 +0200 (Mon, 10 Jul 2023)
Log Message:
-----------
spacekern (10jul23)

Modified Paths:
--------------
    trunk/Master/texmf-dist/doc/lualatex/spacekern/README.md
    trunk/Master/texmf-dist/doc/lualatex/spacekern/spacekern.pdf
    trunk/Master/texmf-dist/doc/lualatex/spacekern/spacekern.tex
    trunk/Master/texmf-dist/tex/lualatex/spacekern/spacekern.lua
    trunk/Master/texmf-dist/tex/lualatex/spacekern/spacekern.sty

Modified: trunk/Master/texmf-dist/doc/lualatex/spacekern/README.md
===================================================================
--- trunk/Master/texmf-dist/doc/lualatex/spacekern/README.md	2023-07-10 19:33:48 UTC (rev 67603)
+++ trunk/Master/texmf-dist/doc/lualatex/spacekern/README.md	2023-07-10 19:33:56 UTC (rev 67604)
@@ -5,7 +5,7 @@
 Second, interword kerning can be applied.
 The package requires LuaLaTeX.
 
-Copyright (c) 2022 Thomas Kelkel kelkel at emaileon.de
+Copyright (c) 2022-2023 Thomas Kelkel kelkel at emaileon.de
 
 The files of this package may be distributed and/or
 modified under the conditions of the LaTeX Project

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

Modified: trunk/Master/texmf-dist/doc/lualatex/spacekern/spacekern.tex
===================================================================
--- trunk/Master/texmf-dist/doc/lualatex/spacekern/spacekern.tex	2023-07-10 19:33:48 UTC (rev 67603)
+++ trunk/Master/texmf-dist/doc/lualatex/spacekern/spacekern.tex	2023-07-10 19:33:56 UTC (rev 67604)
@@ -177,10 +177,10 @@
 	bookmarksopen=true,%
     bookmarksopenlevel=0,%
 	bookmarksnumbered=true,%
-    pdftitle={The spacekern package},
-    pdfsubject={Kerning between words and against space},
-    pdfauthor={Thomas Kelkel},
-    pdfkeywords={tex, latex, kerning}
+    pdftitle={The spacekern package},%
+    pdfsubject={Kerning between words and against space},%
+    pdfauthor={Thomas Kelkel},%
+    pdfkeywords={tex, latex, kerning}%
 }
 
 \setlength{\parindent}{0pt}
@@ -343,7 +343,7 @@
 
 \title{The spacekern package\vspace{.25\baselineskip}\\\superlarge{}Kerning between words and against space}%
 \author{\sublarge{}Thomas Kelkel\vspace{-.25\baselineskip}\\\sublarge{}kelkel at emaileon.de\vspace{-.25\baselineskip}}%
-\date{\addfontfeature{LetterSpace=2}\sublarge{}2022/06/11\quad{}v0.1a}%
+\date{\addfontfeature{LetterSpace=2}\sublarge{}2023/07/08\quad{}v0.3}%
 \maketitle
 
 \section{Introduction}
@@ -382,11 +382,11 @@
 
 \section{Shorthands and Macros}
 
-\addcontentsline{toc}{subsection}{;;}
+\addcontentsline{toc}{subsection}{\semicolon\semicolon}
 
 \textnote{\semicolon\semicolon}Typesets a small breaking space.
 
-\addcontentsline{toc}{subsection}{;;;}
+\addcontentsline{toc}{subsection}{\semicolon\semicolon\semicolon}
 
 \textnote{\semicolon\semicolon\semicolon}Typesets a small non-breaking space.
 
@@ -396,6 +396,6 @@
 
 \section{License}
 
-This package is copyright © 2022 Thomas Kelkel. It may be distributed and/or modified under the conditions of the LaTeX Project Public License, either version 1.3c of this license or (at your option) any later version. This work has the LPPL maintenance status \qq{author maintained}.
+This package is copyright © 2022\kern.1em–\kern.1em2023 Thomas Kelkel. It may be distributed and/or modified under the conditions of the LaTeX Project Public License, either version 1.3c of this license or (at your option) any later version. This work has the LPPL maintenance status \qq{author maintained}.
 
 \end{document}
\ No newline at end of file

Modified: trunk/Master/texmf-dist/tex/lualatex/spacekern/spacekern.lua
===================================================================
--- trunk/Master/texmf-dist/tex/lualatex/spacekern/spacekern.lua	2023-07-10 19:33:48 UTC (rev 67603)
+++ trunk/Master/texmf-dist/tex/lualatex/spacekern/spacekern.lua	2023-07-10 19:33:56 UTC (rev 67604)
@@ -1,4 +1,4 @@
--- Copyright (c) 2022 Thomas Kelkel kelkel at emaileon.de
+-- Copyright (c) 2022-2023 Thomas Kelkel kelkel at emaileon.de
 
 -- This file may be distributed and/or modified under the
 -- conditions of the LaTeX Project Public License, either
@@ -10,34 +10,48 @@
 -- and version 1.3c or later is part of all distributions of
 -- LaTeX version 2009/09/24 or later.
 
--- Version: 0.1a
+-- Version: 0.3
 
 local ID = node.id
 local GLYPH = ID ( "glyph" )
+local DISC = ID ( "disc" )
 local GLUE = ID ( "glue" )
-local KERN = ID ( "kern" )
-local WI = ID ( "whatsit" )
-local BOUND = ID ( "boundary" )
 local PENALTY = ID ( "penalty" )
+local HLIST = ID ( "hlist" )
+local INS = ID ( "ins" )
+
 local SWAPPED = table.swapped
 local SUBTYPES = node.subtypes
-local USERKERN = SWAPPED ( SUBTYPES ("kern") )["userkern"]
+local SPACESKIP = SWAPPED ( SUBTYPES ("glue") )["spaceskip"]
+local LEADERS = SWAPPED ( SUBTYPES ("glue") )["leaders"]
 local LBPENALTY = SWAPPED ( SUBTYPES ("penalty") )["linebreakpenalty"]
-local SPACESKIP = SWAPPED ( SUBTYPES ("glue") )["spaceskip"]
+
 local NEW = node.new
 local REM = node.remove
 local PREV = node.prev
 local NEXT = node.next
+local TAIL = node.tail
 local INS_B = node.insert_before
-local T_ID = node.traverse_id
+local HAS_GLYPH = node.has_glyph
+local T = node.traverse
 local T_GLYPH = node.traverse_glyph
-local WIS = node.whatsits()
-local userdefined
+
 local pairs = pairs
+local type = type
+
+local U = unicode.utf8
+local SUB = U.sub
+local GSUB = U.gsub
+local FIND = U.find
+
 local FLOOR = math.floor
+
 local GET_FONT = font.getfont
+
 local ATC = luatexbase.add_to_callback
 
+-----
+
 local no_iw_kern = false
 
 function spacekern_no_iw_kern ()
@@ -48,51 +62,93 @@
     return FLOOR ( num * 10^dec + 0.5 ) / 10^dec
 end
 
-for key, value in pairs ( WIS ) do
-    if value == "user_defined" then
-        userdefined = key
+local function find_first_last ( n, node_type, last )
+    local d = NEXT
+    if last then
+        d = PREV
+        n = TAIL ( n )
     end
+    while true do
+        if n and n.id == node_type then
+            return n
+        end
+        if d ( n ) then
+            n = d ( n )
+        else
+            return false
+        end
+    end
 end
 
-local function find_glyph ( n, d )
-    if d ( n ) then
-        n = d ( n )
-        while n.id ~= GLYPH do
-            if not d ( n ) or n.id == GLUE or n.id == BOUND or ( n.id == KERN and n.subtype == USERKERN ) then return false end
+local function check_node ( n, space_check, disc_check, last )
+    if n.replace then
+        return find_first_last ( n.replace, GLYPH, last ), space_check, disc_check
+    end
+    return n, space_check, disc_check
+end
+
+local function find_glyph ( n, d, hlist_check, macro )
+    if n then
+        local space_check = false
+        local disc_check = false
+        if hlist_check and ( n.id == GLYPH or n.replace and HAS_GLYPH ( n.replace ) ) then
+            return check_node ( n, space_check, disc_check, d == PREV )
+        elseif not hlist_check then
+            if d ( n ) then
+                n = d ( n )
+            else
+                return false
+            end
+        end
+        while not ( n.id == GLYPH or n.replace and HAS_GLYPH ( n.replace ) ) do
+            if n.id == HLIST and n.head then
+                local point = n.head
+                if d == PREV then
+                    point = TAIL ( point )
+                end
+                return find_glyph ( point, d, true, macro )
+            end
+            if not d ( n ) or n.id == INS or macro and n.id == GLUE and n.width == 0 then
+                return false
+            else
+                if n.id == GLUE and n.subtype == SPACESKIP then
+                    space_check = n
+                elseif n.subtype == LEADERS or n.id == GLUE and n.stretch > 0 then
+                    return false
+                end
+            end
+            if n.id == DISC then
+                disc_check = n
+            end
             n = d ( n )
         end
-    else
-        return false
+        return check_node ( n, space_check, disc_check, d == PREV )
     end
-    return n
+    return false
 end
 
 local function make_kern ( head, font, first_glyph, second_glyph, insert_point )
     local tfmdata = GET_FONT ( font )
-    if tfmdata.resources then
+    if tfmdata and tfmdata.resources then
         local resources = tfmdata.resources
         if resources.sequences then
             local seq = resources.sequences
             for _, t in pairs ( seq ) do
-                if t.steps then
+                if t.steps and ( table.swapped ( t.order )["kern"] or tfmdata.specification.features.raw[t.name] ) then
                     local steps = t.steps
                     for _, k in pairs ( steps ) do
-                        if k.coverage then
-                            local first_number = true
-                            if k.coverage[first_glyph] then
-                                local glyph_table = k.coverage[first_glyph]
-                                if type ( glyph_table ) == "table" then
-                                    for key, value in pairs ( glyph_table ) do
-                                        if key == second_glyph and type ( value ) == "number" and first_number and ( k.format == "move" or tfmdata.specification.features.raw[t.name] ) then
-                                            if tfmdata.specification.features.raw[t.name] then
-                                                first_number = false
-                                            end
-                                            if PREV ( insert_point ).id == PENALTY then
-                                                insert_point = PREV ( insert_point )
-                                            end
-                                            INS_B ( head, insert_point, NEW ( KERN ) )
-                                            PREV ( insert_point ).kern = value / tfmdata.units_per_em * tfmdata.size
+                        if k.coverage and k.coverage[first_glyph] then
+                            local glyph_table = k.coverage[first_glyph]
+                            if type ( glyph_table ) == "table" then
+                                for key, value in pairs ( glyph_table ) do
+                                    if key == second_glyph and type ( value ) == "number" then
+                                        if not ( ( first_glyph == 32 or second_glyph == 32 ) and table.swapped ( t.order )["kern"] ) then
+                                            insert_point.width = insert_point.width + value / tfmdata.units_per_em * tfmdata.size
                                         end
+                                        if first_glyph == 32 or second_glyph == 32 then
+                                            insert_point.stretch = insert_point.stretch + value / tfmdata.units_per_em * tfmdata.size * 0.5
+                                            insert_point.shrink = insert_point.shrink + value / tfmdata.units_per_em * tfmdata.size * 0.33333
+                                        end
                                     end
                                 end
                             end
@@ -102,6 +158,7 @@
             end
         end
     end
+    return head, disc_node
 end
 
 local function check_glyph ( n, d, has_prev_next_glyph, prev_next_glyph )
@@ -120,25 +177,33 @@
     has_prev_glyph, prev_glyph = check_glyph ( n, PREV, has_prev_glyph, prev_glyph )
     has_next_glyph, next_glyph = check_glyph ( n, NEXT, has_next_glyph, next_glyph )
     if has_prev_glyph and prev_glyph.char and prev_glyph.font then
-        make_kern ( head, prev_glyph.font, prev_glyph.char, 32, n )
+        head = make_kern ( head, prev_glyph.font, prev_glyph.char, 32, n )
     end
     if has_next_glyph and next_glyph.char and next_glyph.font then
-        make_kern ( head, next_glyph.font, 32, next_glyph.char, n )
+        head = make_kern ( head, next_glyph.font, 32, next_glyph.char, n )
     end
-    if not no_iw_kern and has_prev_glyph and has_next_glyph and prev_glyph.char and next_glyph.char and prev_glyph.font and next_glyph.font and ( prev_glyph.font == next_glyph.font ) then
-        make_kern ( head, prev_glyph.font, prev_glyph.char, next_glyph.char, n )
+    if not no_iw_kern and has_prev_glyph and has_next_glyph and prev_glyph.char and next_glyph.char and prev_glyph.font and next_glyph.font then
+        local tfmdata = GET_FONT ( prev_glyph.font )
+        if tfmdata and tfmdata.name then
+            local font_id = GSUB ( SUB ( tfmdata.name, 1, FIND ( tfmdata.name, ":" ) - 1 ), "\"", "" )
+            local second_tfmdata = GET_FONT ( next_glyph.font )
+            if second_tfmdata and second_tfmdata.name then
+                local second_font_id = GSUB ( SUB ( second_tfmdata.name, 1, FIND ( second_tfmdata.name, ":" ) - 1 ), "\"", "" )
+                if font_id == second_font_id then
+                    head = make_kern ( head, prev_glyph.font, prev_glyph.char, next_glyph.char, n )
+                end
+            end
+        end
     end
+    return head
 end
 
-local function make_glues_and_kerns ( head )
-    for n in T_ID ( GLUE, head ) do
-        make_kerns ( head, n )
-    end
+local function make_short_spaces ( head )
     for n in T_GLYPH ( head ) do
         if n.char and n.char == 59 and ( not find_glyph ( n, PREV ) or find_glyph ( n, PREV ).char ~= 59 ) then
-            if find_glyph ( n, NEXT ) then
+            if find_glyph ( n, NEXT, false, true ) then
                 local next_glyph = n
-                next_glyph = find_glyph ( n, NEXT )
+                next_glyph = find_glyph ( n, NEXT, false, true )
                 if next_glyph.char and next_glyph.char == 59 then
                     REM ( head, next_glyph )
                     local SIZE = 0
@@ -152,9 +217,11 @@
                     local glue_node = PREV ( n )
                     glue_node.subtype = SPACESKIP
                     glue_node.width = round ( SIZE * .16667, 0 )
+                    glue_node.stretch = glue_node.width * 0.5
+                    glue_node.shrink = glue_node.width * 0.33333
                     local has_next_glyph = false
-                    if find_glyph ( n, NEXT ) then
-                        next_glyph = find_glyph ( n, NEXT )
+                    if find_glyph ( n, NEXT, false, true ) then
+                        next_glyph = find_glyph ( n, NEXT, false, true )
                         has_next_glyph = true
                     end
                     if has_next_glyph and next_glyph.char and next_glyph.char == 59 then
@@ -164,7 +231,6 @@
                         REM ( head, next_glyph )
                     end
                     REM ( head, n )
-                    make_kerns ( head, glue_node )
                 end
             end
         end
@@ -171,4 +237,15 @@
     end
 end
 
-ATC ( "ligaturing", make_glues_and_kerns, "kern between words and against space", 1 )
\ No newline at end of file
+local function make_glues_and_kerns ( head )
+    for n in T ( head ) do
+        if n.id == GLUE and n.subtype == SPACESKIP then
+            head = make_kerns ( head, n )
+        end
+    end
+    return head
+end
+
+ATC ( "ligaturing", make_short_spaces, "make short spaces", 1 )
+ATC ( "pre_linebreak_filter", make_glues_and_kerns, "kern between words and against space preline", 1 )
+ATC ( "hpack_filter", make_glues_and_kerns, "kern between words and against space hpack" )
\ No newline at end of file

Modified: trunk/Master/texmf-dist/tex/lualatex/spacekern/spacekern.sty
===================================================================
--- trunk/Master/texmf-dist/tex/lualatex/spacekern/spacekern.sty	2023-07-10 19:33:48 UTC (rev 67603)
+++ trunk/Master/texmf-dist/tex/lualatex/spacekern/spacekern.sty	2023-07-10 19:33:56 UTC (rev 67604)
@@ -1,4 +1,4 @@
-% Copyright (c) 2022 Thomas Kelkel kelkel at emaileon.de
+% Copyright (c) 2022-2023 Thomas Kelkel kelkel at emaileon.de
 
 % This file may be distributed and/or modified under the
 % conditions of the LaTeX Project Public License, either
@@ -10,7 +10,7 @@
 % and version 1.3c or later is part of all distributions of
 % LaTeX version 2009/09/24 or later.
 
-\ProvidesPackage{spacekern}[2022/06/11 v0.1a Kerning between words and against space]
+\ProvidesPackage{spacekern}[2023/07/08 v0.3 Kerning between words and against space]
 \RequirePackage{ifluatex,luatexbase}
 
 \ifluatex



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