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.