summaryrefslogtreecommitdiff
path: root/tex
diff options
context:
space:
mode:
authorHans Hagen <pragma@wxs.nl>2022-03-24 21:42:40 +0100
committerContext Git Mirror Bot <phg@phi-gamma.net>2022-03-24 21:42:40 +0100
commit6a2738578157926c6ebd64048ddabb7d923b2be5 (patch)
tree908336b6d20b32c00548f2ee75ef8ae947979fb9 /tex
parent188632f4b0f71c5170a20f1b151bde68f603bfd9 (diff)
downloadcontext-6a2738578157926c6ebd64048ddabb7d923b2be5.tar.gz
2022-03-24 21:17:00
Diffstat (limited to 'tex')
-rw-r--r--tex/context/base/mkii/cont-new.mkii2
-rw-r--r--tex/context/base/mkii/context.mkii2
-rw-r--r--tex/context/base/mkiv/cont-new.mkiv2
-rw-r--r--tex/context/base/mkiv/context.mkiv2
-rw-r--r--tex/context/base/mkiv/font-dsp.lua1
-rw-r--r--tex/context/base/mkiv/font-map.lua6
-rw-r--r--tex/context/base/mkiv/font-mis.lua2
-rw-r--r--tex/context/base/mkiv/font-otl.lua2
-rw-r--r--tex/context/base/mkiv/font-otr.lua6
-rw-r--r--tex/context/base/mkiv/font-oup.lua210
-rw-r--r--tex/context/base/mkiv/font-ttf.lua235
-rw-r--r--tex/context/base/mkiv/l-os.lua2
-rw-r--r--tex/context/base/mkiv/mtx-context-compare.tex4
-rw-r--r--tex/context/base/mkiv/mult-low.lua2
-rw-r--r--tex/context/base/mkiv/mult-prm.lua15
-rw-r--r--tex/context/base/mkiv/status-files.pdfbin24667 -> 24656 bytes
-rw-r--r--tex/context/base/mkiv/status-lua.pdfbin258099 -> 258263 bytes
-rw-r--r--tex/context/base/mkxl/cont-new.mkxl2
-rw-r--r--tex/context/base/mkxl/context.mkxl2
-rw-r--r--tex/context/base/mkxl/font-imp-math.lmt54
-rw-r--r--tex/context/base/mkxl/font-otl.lmt2
-rw-r--r--tex/context/base/mkxl/libs-imp-zint.lmt56
-rw-r--r--tex/context/base/mkxl/math-act.lmt87
-rw-r--r--tex/context/base/mkxl/math-ali.mkxl470
-rw-r--r--tex/context/base/mkxl/math-fen.mkxl32
-rw-r--r--tex/context/base/mkxl/math-ini.lmt4
-rw-r--r--tex/context/base/mkxl/math-ini.mkxl88
-rw-r--r--tex/context/base/mkxl/math-noa.lmt144
-rw-r--r--tex/context/base/mkxl/meta-ini.mkxl2
-rw-r--r--tex/context/base/mkxl/mlib-lmp.lmt26
-rw-r--r--tex/context/base/mkxl/mlib-lua.lmt2
-rw-r--r--tex/context/base/mkxl/node-tsk.lmt10
-rw-r--r--tex/context/base/mkxl/pack-box.mkxl24
-rw-r--r--tex/context/base/mkxl/pack-mat.mkxl2
-rw-r--r--tex/context/base/mkxl/page-one.mkxl10
-rw-r--r--tex/context/base/mkxl/spac-ver.mkxl5
-rw-r--r--tex/context/base/mkxl/tabl-xtb.lmt1310
-rw-r--r--tex/context/base/mkxl/tabl-xtb.mklx2
-rw-r--r--tex/context/base/mkxl/task-ini.lmt2
-rw-r--r--tex/context/base/mkxl/trac-vis.lmt2
-rw-r--r--tex/context/fonts/mkiv/libertinus-math.lfg54
-rw-r--r--tex/context/fonts/mkiv/lucida-opentype-math.lfg44
-rw-r--r--tex/context/fonts/mkiv/stix-two-math.lfg14
-rw-r--r--tex/context/fonts/mkiv/type-imp-lucida-opentype.mkiv13
-rw-r--r--tex/context/fonts/mkiv/type-imp-stix.mkiv3
-rw-r--r--tex/context/fonts/mkiv/type-imp-xits.mkiv14
-rw-r--r--tex/context/fonts/mkiv/xits-math.lfg14
-rw-r--r--tex/generic/context/luatex/luatex-fonts-merged.lua357
48 files changed, 2648 insertions, 696 deletions
diff --git a/tex/context/base/mkii/cont-new.mkii b/tex/context/base/mkii/cont-new.mkii
index cad7b57e1..4b51600b4 100644
--- a/tex/context/base/mkii/cont-new.mkii
+++ b/tex/context/base/mkii/cont-new.mkii
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\newcontextversion{2022.03.12 11:24}
+\newcontextversion{2022.03.24 21:14}
%D This file is loaded at runtime, thereby providing an
%D excellent place for hacks, patches, extensions and new
diff --git a/tex/context/base/mkii/context.mkii b/tex/context/base/mkii/context.mkii
index 30265042e..ac446c2e1 100644
--- a/tex/context/base/mkii/context.mkii
+++ b/tex/context/base/mkii/context.mkii
@@ -20,7 +20,7 @@
%D your styles an modules.
\edef\contextformat {\jobname}
-\edef\contextversion{2022.03.12 11:24}
+\edef\contextversion{2022.03.24 21:14}
%D For those who want to use this:
diff --git a/tex/context/base/mkiv/cont-new.mkiv b/tex/context/base/mkiv/cont-new.mkiv
index f33357f04..883269f4b 100644
--- a/tex/context/base/mkiv/cont-new.mkiv
+++ b/tex/context/base/mkiv/cont-new.mkiv
@@ -13,7 +13,7 @@
% \normalend % uncomment this to get the real base runtime
-\newcontextversion{2022.03.12 11:24}
+\newcontextversion{2022.03.24 21:14}
%D This file is loaded at runtime, thereby providing an excellent place for hacks,
%D patches, extensions and new features. There can be local overloads in cont-loc
diff --git a/tex/context/base/mkiv/context.mkiv b/tex/context/base/mkiv/context.mkiv
index 1e81770dc..7f27d0ba5 100644
--- a/tex/context/base/mkiv/context.mkiv
+++ b/tex/context/base/mkiv/context.mkiv
@@ -49,7 +49,7 @@
%D {YYYY.MM.DD HH:MM} format.
\edef\contextformat {\jobname}
-\edef\contextversion{2022.03.12 11:24}
+\edef\contextversion{2022.03.24 21:14}
%D Kind of special:
diff --git a/tex/context/base/mkiv/font-dsp.lua b/tex/context/base/mkiv/font-dsp.lua
index 7028f7c08..74a0a1f38 100644
--- a/tex/context/base/mkiv/font-dsp.lua
+++ b/tex/context/base/mkiv/font-dsp.lua
@@ -3820,6 +3820,7 @@ function readers.hvar(f,fontdata,specification)
local variations = { }
local innerindex = { } -- size is mapcount
local outerindex = { } -- size is mapcount
+ local deltas = { }
if variationoffset > 0 then
regions, deltas = readvariationdata(f,variationoffset,factors)
diff --git a/tex/context/base/mkiv/font-map.lua b/tex/context/base/mkiv/font-map.lua
index c983ea963..4aa937ed1 100644
--- a/tex/context/base/mkiv/font-map.lua
+++ b/tex/context/base/mkiv/font-map.lua
@@ -253,9 +253,9 @@ function mappings.addtounicode(data,filename,checklookups,forceligatures)
local usedmap = cidinfo and fonts.cid.getmap(cidinfo)
local uparser = makenameparser() -- hm, every time?
if usedmap then
- oparser = usedmap and makenameparser(cidinfo.ordering)
- cidnames = usedmap.names
- cidcodes = usedmap.unicodes
+ oparser = usedmap and makenameparser(cidinfo.ordering)
+ cidnames = usedmap.names
+ cidcodes = usedmap.unicodes
end
local ns = 0
local nl = 0
diff --git a/tex/context/base/mkiv/font-mis.lua b/tex/context/base/mkiv/font-mis.lua
index 9bb8d4cc1..c294bd638 100644
--- a/tex/context/base/mkiv/font-mis.lua
+++ b/tex/context/base/mkiv/font-mis.lua
@@ -21,7 +21,7 @@ local readers = otf.readers
if readers then
- otf.version = otf.version or 3.119
+ otf.version = otf.version or 3.120
otf.cache = otf.cache or containers.define("fonts", "otl", otf.version, true)
function fonts.helpers.getfeatures(name,save)
diff --git a/tex/context/base/mkiv/font-otl.lua b/tex/context/base/mkiv/font-otl.lua
index ae2dda4f3..f36e533ca 100644
--- a/tex/context/base/mkiv/font-otl.lua
+++ b/tex/context/base/mkiv/font-otl.lua
@@ -52,7 +52,7 @@ local report_otf = logs.reporter("fonts","otf loading")
local fonts = fonts
local otf = fonts.handlers.otf
-otf.version = 3.119 -- beware: also sync font-mis.lua and in mtx-fonts
+otf.version = 3.120 -- beware: also sync font-mis.lua and in mtx-fonts
otf.cache = containers.define("fonts", "otl", otf.version, true)
otf.svgcache = containers.define("fonts", "svg", otf.version, true)
otf.pngcache = containers.define("fonts", "png", otf.version, true)
diff --git a/tex/context/base/mkiv/font-otr.lua b/tex/context/base/mkiv/font-otr.lua
index 286367ed9..339de109f 100644
--- a/tex/context/base/mkiv/font-otr.lua
+++ b/tex/context/base/mkiv/font-otr.lua
@@ -2499,15 +2499,15 @@ function readers.getinfo(filename,specification) -- string, nil|number|table
end
end
-function readers.rehash(fontdata,hashmethod)
+function readers.rehash() -- fontdata,hashmethod
report("the %a helper is not yet implemented","rehash")
end
-function readers.checkhash(fontdata)
+function readers.checkhash() --fontdata
report("the %a helper is not yet implemented","checkhash")
end
-function readers.pack(fontdata,hashmethod)
+function readers.pack() -- fontdata,hashmethod
report("the %a helper is not yet implemented","pack")
end
diff --git a/tex/context/base/mkiv/font-oup.lua b/tex/context/base/mkiv/font-oup.lua
index 3bd2fe482..248aad04d 100644
--- a/tex/context/base/mkiv/font-oup.lua
+++ b/tex/context/base/mkiv/font-oup.lua
@@ -10,6 +10,7 @@ local next, type = next, type
local P, R, S = lpeg.P, lpeg.R, lpeg.S
local lpegmatch = lpeg.match
local insert, remove, copy, unpack = table.insert, table.remove, table.copy, table.unpack
+local find = string.find
local formatters = string.formatters
local sortedkeys = table.sortedkeys
@@ -944,15 +945,18 @@ local function unifyglyphs(fontdata,usenames)
return indices, names
end
-local p_crappyname do
+local stripredundant do
+
local p_hex = R("af","AF","09")
local p_digit = R("09")
local p_done = S("._-")^0 + P(-1)
+ -- local p_style = P(".ss") * p_digit * p_digit * P(-1)
+ local p_style = P(".")
local p_alpha = R("az","AZ")
local p_ALPHA = R("AZ")
- p_crappyname = (
+ local p_crappyname = (
-- (P("uni") + P("UNI") + P("Uni") + P("U") + P("u"))
lpeg.utfchartabletopattern({ "uni", "u" },true)
* S("Xx_")^0
@@ -980,56 +984,182 @@ local p_crappyname do
* P(1)^1
) * p_done
-end
+ -- In context we only keep glyph names because of tracing and access by name
+ -- so weird names make no sense.
--- In context we only keep glyph names because of tracing and access by name
--- so weird names make no sense.
+ if context then
-local forcekeep = false -- only for testing something
+ local forcekeep = false -- only for testing something
+-- local forcekeep = true
-directives.register("otf.keepnames",function(v)
- report_cleanup("keeping weird glyph names, expect larger files and more memory usage")
- forcekeep = v
-end)
+ directives.register("otf.keepnames",function(v)
+ report_cleanup("keeping weird glyph names, expect larger files and more memory usage")
+ forcekeep = v
+ end)
-local function stripredundant(fontdata)
- local descriptions = fontdata.descriptions
- if descriptions then
- local n = 0
- local c = 0
- -- in context we always strip
- if (not context and fonts.privateoffsets.keepnames) or forcekeep then
- for unicode, d in next, descriptions do
- if d.class == "base" then
- d.class = nil
- c = c + 1
+ -- local p_lesscrappyname =
+ -- lpeg.utfchartabletopattern({ "uni", "u" },true)
+ -- * S("Xx")^0
+ -- * p_hex^1
+ -- * p_style
+
+ local function stripvariants(descriptions,list)
+ local n = list and #list or 0
+ if n > 0 then
+ for i=1,n do
+ local g = list[i]
+ if g then
+ local d = descriptions[g]
+ if d and d.name then
+ d.name = nil
+ n = n + 1
+ end
+ end
end
end
- else
- for unicode, d in next, descriptions do
- local name = d.name
- if name and lpegmatch(p_crappyname,name) then
- d.name = nil
- n = n + 1
+ return n
+ end
+
+ local function stripparts(descriptions,list)
+ local n = list and #list or 0
+ if n > 0 then
+ for i=1,n do
+ local g = list[i].glyph
+ if g then
+ local d = descriptions[g]
+ if d and d.name then
+ d.name = nil
+ n = n + 1
+ end
+ end
end
- if d.class == "base" then
- d.class = nil
- c = c + 1
+ end
+ return n
+ end
+
+ -- local function collectsimple(fontdata)
+ -- local resources = fontdata.resources
+ -- local sequences = resources and resources.sequences
+ -- if sequences then
+ -- local keeplist = { }
+ -- for i=1,#sequences do
+ -- local s = sequences[i]
+ -- if s.type == "gsub_single" then
+ -- -- only simple ones
+ -- local features = s.features
+ -- local steps = s.steps
+ -- if features and steps then
+ -- local okay = false
+ -- for k, v in next, features do
+ -- if find(k,"^ss%d%d") then
+ -- okay = true
+ -- break
+ -- end
+ -- end
+ -- if okay then
+ -- for i=1,#steps do
+ -- local coverage = steps[i].coverage
+ -- if coverage then
+ -- for k, v in next, coverage do
+ -- keeplist[k] = v
+ -- end
+ -- end
+ -- end
+ -- end
+ -- end
+ -- end
+ -- end
+ -- return next(keeplist) and keeplist or nil
+ -- end
+ -- end
+
+ local function collectsimple(fontdata)
+ return nil
+ end
+
+ stripredundant = function(fontdata)
+ local descriptions = fontdata.descriptions
+ if descriptions then
+ local n = 0
+ local c = 0
+ for unicode, d in next, descriptions do
+ local m = d.math
+ if m then
+ n = n + stripvariants(descriptions,m.vvariants)
+ n = n + stripvariants(descriptions,m.hvariants)
+ n = n + stripparts (descriptions,m.vparts)
+ n = n + stripparts (descriptions,m.hparts)
+ end
+ end
+ if forcekeep then
+ for unicode, d in next, descriptions do
+ if d.class == "base" then
+ d.class = nil
+ c = c + 1
+ end
+ end
+ else
+ local keeplist = collectsimple(fontdata)
+ for unicode, d in next, descriptions do
+ local name = d.name
+ if name then
+ -- if lpegmatch(p_lesscrappyname,name) then
+ if keeplist and keeplist[name] then
+ -- keep name
+ elseif lpegmatch(p_crappyname,name) then
+ d.name = nil
+ n = n + 1
+ end
+ end
+ if d.class == "base" then
+ d.class = nil
+ c = c + 1
+ end
+ end
+ end
+ if trace_cleanup then
+ if n > 0 then
+ report_cleanup("%s bogus names removed (verbose unicode)",n)
+ end
+ if c > 0 then
+ report_cleanup("%s base class tags removed (default is base)",c)
+ end
end
end
end
- if trace_cleanup then
- if n > 0 then
- report_cleanup("%s bogus names removed (verbose unicode)",n)
- end
- if c > 0 then
- report_cleanup("%s base class tags removed (default is base)",c)
+
+ else
+
+ stripredundant = function(fontdata)
+ local descriptions = fontdata.descriptions
+ if descriptions then
+ if fonts.privateoffsets.keepnames then
+ for unicode, d in next, descriptions do
+ if d.class == "base" then
+ d.class = nil
+ end
+ end
+ else
+ for unicode, d in next, descriptions do
+ local name = d.name
+ if name then
+ if lpegmatch(p_crappyname,name) then
+ d.name = nil
+ end
+ end
+ if d.class == "base" then
+ d.class = nil
+ end
+ end
+ end
end
end
+
end
-end
-readers.stripredundant = stripredundant
+ readers.stripredundant = stripredundant
+
+end
function readers.getcomponents(fontdata) -- handy for resolving ligatures when names are missing
local resources = fontdata.resources
@@ -1128,8 +1258,7 @@ readers.unifymissing = unifymissing
function readers.rehash(fontdata,hashmethod) -- TODO: combine loops in one
if not (fontdata and fontdata.glyphs) then
return
- end
- if hashmethod == "indices" then
+ elseif hashmethod == "indices" then
fontdata.hashmethod = "indices"
elseif hashmethod == "names" then
fontdata.hashmethod = "names"
@@ -1137,7 +1266,6 @@ function readers.rehash(fontdata,hashmethod) -- TODO: combine loops in one
unifyresources(fontdata,indices)
copyduplicates(fontdata)
unifymissing(fontdata)
- -- stripredundant(fontdata)
else
fontdata.hashmethod = "unicodes"
local indices = unifyglyphs(fontdata)
diff --git a/tex/context/base/mkiv/font-ttf.lua b/tex/context/base/mkiv/font-ttf.lua
index a2658d595..d1a3972b2 100644
--- a/tex/context/base/mkiv/font-ttf.lua
+++ b/tex/context/base/mkiv/font-ttf.lua
@@ -247,115 +247,148 @@ local function applyaxis(glyph,shape,deltas,dowidth)
-- Not the most efficient solution but we seldom do this. We
-- actually need to avoid the extra points here but I'll deal
-- with that when needed.
- local function find(i)
- local prv = cnt
- for j=1,cnt do
- local nxt = dpoints[j]
- if nxt == i then
- return false, j, false
- elseif nxt > i then
- return prv, false, j
- end
- prv = j
- end
- return prv, false, 1
- end
- -- We need the first and last points untouched so we first
- -- collect data.
- for i=1,nofpoints do
- local d1, d2, d3 = find(i)
- local p2 = points[i]
- if d2 then
- xv[i] = xvalues[d2]
- yv[i] = yvalues[d2]
- else
- local n1 = dpoints[d1]
- local n3 = dpoints[d3]
- -- Some day I need to figure out these extra points but
- -- I'll wait till the standard is more clear and fonts
- -- become better (ntg-context: fraunces.ttf > abcdef).
- if n1 > nofpoints then
- n1 = nofpoints
- end
- if n3 > nofpoints then
- n3 = nofpoints
- end
- --
- local p1 = points[n1]
- local p3 = points[n3]
- local p1x = p1[1]
- local p2x = p2[1]
- local p3x = p3[1]
- local p1y = p1[2]
- local p2y = p2[2]
- local p3y = p3[2]
- local x1 = xvalues[d1]
- local y1 = yvalues[d1]
- local x3 = xvalues[d3]
- local y3 = yvalues[d3]
- --
- local fx
- local fy
- --
- if p1x == p3x then
- if x1 == x3 then
- fx = x1
- else
- fx = 0
- end
- elseif p2x <= min(p1x,p3x) then
- if p1x < p3x then
- fx = x1
- else
- fx = x3
- end
- elseif p2x >= max(p1x,p3x) then
- if p1x > p3x then
- fx = x1
- else
- fx = x3
+ local contours = shape.contours
+ local nofcontours = #contours
+ local first = 1
+ local firstindex = 1
+ for contour=1,nofcontours do
+ local last = contours[contour]
+ if last >= first then
+ local lastindex = cnt
+ if firstindex < cnt then
+ for currentindex=firstindex,cnt do
+ local found = dpoints[currentindex]
+ if found <= first then
+ firstindex = currentindex
+ end
+ if found == last then
+ lastindex = currentindex
+ break;
+ elseif found > last then
+ break
+ end
end
- else
- fx = (p2x - p1x)/(p3x - p1x)
- fx = (1 - fx) * x1 + fx * x3
end
- --
- if p1y == p3y then
- if y1 == y3 then
- fy = y1
- else
- fy = 0
- end
- elseif p2y <= min(p1y,p3y) then
- if p1y < p3y then
- fy = y1
- else
- fy = y3
+ -- print("unicode: ",glyph.unicode or "?")
+ -- print("contour: ",first,contour,last)
+ -- print("index : ",firstindex,lastindex,cnt)
+ -- print("points : ",dpoints[firstindex],dpoints[lastindex])
+ local function find(i)
+ local prv = lastindex
+ for j=firstindex,lastindex do
+ local nxt = dpoints[j]
+ if nxt == i then
+ return false, j, false
+ elseif nxt > i then
+ return prv, false, j
+ end
+ prv = j
end
- elseif p2y >= max(p1y,p3y) then
- if p1y > p3y then
- fy = y1
+ return prv, false, firstindex
+ end
+ -- We need the first and last points untouched so we first
+ -- collect data.
+ for point=first,last do
+ local d1, d2, d3 = find(point)
+ local p2 = points[point]
+ if d2 then
+ xv[point] = xvalues[d2]
+ yv[point] = yvalues[d2]
else
- fy = y3
+ local n1 = dpoints[d1]
+ local n3 = dpoints[d3]
+ -- Some day I need to figure out these extra points but
+ -- I'll wait till the standard is more clear and fonts
+ -- become better (ntg-context: fraunces.ttf > abcdef).
+ if n1 > nofpoints then
+ n1 = nofpoints
+ end
+ if n3 > nofpoints then
+ n3 = nofpoints
+ end
+ --
+ local p1 = points[n1]
+ local p3 = points[n3]
+ local p1x = p1[1]
+ local p2x = p2[1]
+ local p3x = p3[1]
+ local p1y = p1[2]
+ local p2y = p2[2]
+ local p3y = p3[2]
+ local x1 = xvalues[d1]
+ local y1 = yvalues[d1]
+ local x3 = xvalues[d3]
+ local y3 = yvalues[d3]
+ --
+ local fx
+ local fy
+ --
+ if p1x == p3x then
+ if x1 == x3 then
+ fx = x1
+ else
+ fx = 0
+ end
+ elseif p2x <= min(p1x,p3x) then
+ if p1x < p3x then
+ fx = x1
+ else
+ fx = x3
+ end
+ elseif p2x >= max(p1x,p3x) then
+ if p1x > p3x then
+ fx = x1
+ else
+ fx = x3
+ end
+ else
+ fx = (p2x - p1x)/(p3x - p1x)
+ fx = (1 - fx) * x1 + fx * x3
+ end
+ --
+ if p1y == p3y then
+ if y1 == y3 then
+ fy = y1
+ else
+ fy = 0
+ end
+ elseif p2y <= min(p1y,p3y) then
+ if p1y < p3y then
+ fy = y1
+ else
+ fy = y3
+ end
+ elseif p2y >= max(p1y,p3y) then
+ if p1y > p3y then
+ fy = y1
+ else
+ fy = y3
+ end
+ else
+ fy = (p2y - p1y)/(p3y - p1y)
+ fy = (1 - fy) * y1 + fy * y3
+ end
+ -- -- maybe:
+ -- if p1y ~= p3y then
+ -- fy = (p2y - p1y)/(p3y - p1y)
+ -- fy = (1 - fy) * y1 + fy * y3
+ -- elseif abs(p1y-p2y) < abs(p3y-p2y) then
+ -- fy = y1
+ -- else
+ -- fy = y3
+ -- end
+ --
+ xv[point] = fx
+ yv[point] = fy
end
- else
- fy = (p2y - p1y)/(p3y - p1y)
- fy = (1 - fy) * y1 + fy * y3
end
- -- -- maybe:
- -- if p1y ~= p3y then
- -- fy = (p2y - p1y)/(p3y - p1y)
- -- fy = (1 - fy) * y1 + fy * y3
- -- elseif abs(p1y-p2y) < abs(p3y-p2y) then
- -- fy = y1
- -- else
- -- fy = y3
- -- end
- --
- xv[i] = fx
- yv[i] = fy
+ if lastindex < cnt then
+ firstindex = lastindex + 1
+ end
end
+ first = last + 1
end
+
for i=1,nofpoints do
local pi = points[i]
local fx = xv[i]
diff --git a/tex/context/base/mkiv/l-os.lua b/tex/context/base/mkiv/l-os.lua
index 7f4f3876b..faae76881 100644
--- a/tex/context/base/mkiv/l-os.lua
+++ b/tex/context/base/mkiv/l-os.lua
@@ -168,7 +168,7 @@ if not os.__getenv__ then
end
function os.getenv(k)
- local K = upper(k)
+ local K = upper(k) -- hm utf
local v = osenv[K] or osgetenv(K) or osgetenv(k)
if v == "" then
return nil
diff --git a/tex/context/base/mkiv/mtx-context-compare.tex b/tex/context/base/mkiv/mtx-context-compare.tex
index 163ea5747..16f8a5408 100644
--- a/tex/context/base/mkiv/mtx-context-compare.tex
+++ b/tex/context/base/mkiv/mtx-context-compare.tex
@@ -69,8 +69,8 @@ local function check(name)
return used
end
-local one = check(fileone)
-local two = check(filetwo)
+local one = check(fileone) -- can crash
+local two = check(filetwo) -- can crash
if not one then
report("invalid file %a",fileone)
diff --git a/tex/context/base/mkiv/mult-low.lua b/tex/context/base/mkiv/mult-low.lua
index e5feab5d6..f24c66d12 100644
--- a/tex/context/base/mkiv/mult-low.lua
+++ b/tex/context/base/mkiv/mult-low.lua
@@ -164,7 +164,7 @@ return {
"mathrelationcode", "mathrelcode", "mathopencode", "mathclosecode", "mathpunctuationcode",
"mathpunctcode", "mathovercode", "mathundercode", "mathinnercode", "mathradicalcode",
"mathfractioncode", "mathmiddlecode", "mathaccentcode", "mathfencedcode", "mathghostcode",
- "mathvariablecode", "mathactivecode", "mathvcentercode",
+ "mathvariablecode", "mathactivecode", "mathvcentercode", "mathconstructcode", "mathwrappedcode",
"mathbegincode", "mathendcode", "mathexplicitcode", "mathdivisioncode", "mathfactorialcode",
--
"mathimaginarycode", "mathdifferentialcode", "mathexponentialcode", "mathfunctioncode", "mathdigitcode",
diff --git a/tex/context/base/mkiv/mult-prm.lua b/tex/context/base/mkiv/mult-prm.lua
index bbc41176b..b366ea336 100644
--- a/tex/context/base/mkiv/mult-prm.lua
+++ b/tex/context/base/mkiv/mult-prm.lua
@@ -77,7 +77,10 @@ return {
"Uhextensible",
"Uleft",
"Umathaccent",
+ "Umathaccentbasedepth",
"Umathaccentbaseheight",
+ "Umathaccentbottomshiftdown",
+ "Umathaccenttopshiftup",
"Umathaccentvariant",
"Umathadapttoleft",
"Umathadapttoright",
@@ -106,6 +109,10 @@ return {
"Umathextrasupprespace",
"Umathextrasupshift",
"Umathextrasupspace",
+ "Umathflattenedaccentbasedepth",
+ "Umathflattenedaccentbaseheight",
+ "Umathflattenedaccentbottomshiftdown",
+ "Umathflattenedaccenttopshiftup",
"Umathfractiondelsize",
"Umathfractiondenomdown",
"Umathfractiondenomvgap",
@@ -143,8 +150,9 @@ return {
"Umathprimeraise",
"Umathprimeshiftdrop",
"Umathprimeshiftup",
- "Umathprimesupspace",
+ "Umathprimespaceafter",
"Umathprimevariant",
+ "Umathprimewidth",
"Umathquad",
"Umathradicaldegreeafter",
"Umathradicaldegreebefore",
@@ -443,12 +451,14 @@ return {
"luatexversion",
"mathaccent",
"mathatom",
+ "mathatomglue",
"mathatomskip",
"mathbackwardpenalties",
- "mathcontrolmode",
+ "mathbeginclass",
"mathdelimitersmode",
"mathdirection",
"mathdisplayskipmode",
+ "mathendclass",
"matheqnogapstep",
"mathfenced",
"mathfencesmode",
@@ -463,7 +473,6 @@ return {
"mathrad",
"mathrulesfam",
"mathrulesmode",
- "mathrulethicknessmode",
"mathscale",
"mathscriptboxmode",
"mathscriptcharmode",
diff --git a/tex/context/base/mkiv/status-files.pdf b/tex/context/base/mkiv/status-files.pdf
index 75450daa5..3f451abe0 100644
--- a/tex/context/base/mkiv/status-files.pdf
+++ b/tex/context/base/mkiv/status-files.pdf
Binary files differ
diff --git a/tex/context/base/mkiv/status-lua.pdf b/tex/context/base/mkiv/status-lua.pdf
index 63b45c4c1..b642259b7 100644
--- a/tex/context/base/mkiv/status-lua.pdf
+++ b/tex/context/base/mkiv/status-lua.pdf
Binary files differ
diff --git a/tex/context/base/mkxl/cont-new.mkxl b/tex/context/base/mkxl/cont-new.mkxl
index 91c21c84d..6f4698847 100644
--- a/tex/context/base/mkxl/cont-new.mkxl
+++ b/tex/context/base/mkxl/cont-new.mkxl
@@ -13,7 +13,7 @@
% \normalend % uncomment this to get the real base runtime
-\newcontextversion{2022.03.12 11:24}
+\newcontextversion{2022.03.24 21:14}
%D This file is loaded at runtime, thereby providing an excellent place for hacks,
%D patches, extensions and new features. There can be local overloads in cont-loc
diff --git a/tex/context/base/mkxl/context.mkxl b/tex/context/base/mkxl/context.mkxl
index 57fc8e155..6beb0171b 100644
--- a/tex/context/base/mkxl/context.mkxl
+++ b/tex/context/base/mkxl/context.mkxl
@@ -29,7 +29,7 @@
%D {YYYY.MM.DD HH:MM} format.
\immutable\edef\contextformat {\jobname}
-\immutable\edef\contextversion{2022.03.12 11:24}
+\immutable\edef\contextversion{2022.03.24 21:14}
%overloadmode 1 % check frozen / warning
%overloadmode 2 % check frozen / error
diff --git a/tex/context/base/mkxl/font-imp-math.lmt b/tex/context/base/mkxl/font-imp-math.lmt
index 2f9c94d16..9811cb7c8 100644
--- a/tex/context/base/mkxl/font-imp-math.lmt
+++ b/tex/context/base/mkxl/font-imp-math.lmt
@@ -13,6 +13,8 @@ local helpers = fonts.helpers
local registerotffeature = fonts.handlers.otf.features.register
local setmetatableindex = table.setmetatableindex
+local sortedhash = table.sortedhash
+local copytable = table.copy
local texconditionals = tex.conditionals
@@ -307,3 +309,55 @@ registerotffeature {
node = initialize,
}
}
+
+-- todo: document our privates
+
+-- This horrible hack is needed because when opentype math showed up and math was
+-- added to unicode folks had forgotten about different script shapes so we not only
+-- have a retrospective variant selector but inconsistent defaults. What a mess it
+-- is. So the quick and dirty solution is:
+--
+-- add copies in private slots
+-- use a pseudo feature to acess those
+-- and optionally afterwards replace the original slots
+
+local coverage = { }
+
+local function initialize(tfmdata,value)
+ if value then
+ if not next(coverage) then
+ for k, char in next, mathematics.alphabets.sr.tf.lcletters do
+ coverage[char] = 0xFE800 + k
+ end
+ for k, char in next, mathematics.alphabets.sr.tf.ucletters do
+ coverage[char] = 0xFE800 + k
+ end
+ fonts.handlers.otf.addfeature {
+ name = "savemathscripts",
+ type = "substitution",
+ data = coverage,
+ }
+ end
+ local characters = tfmdata.characters
+ local descriptions = tfmdata.descriptions
+ for char, private in next, coverage do
+ local data = characters[char]
+ if data and not characters[private] then
+ -- otherwise we need a virtual
+ characters [private] = copytable(data)
+ descriptions[private] = copytable(descriptions[char])
+ end
+ end
+ end
+end
+
+registerotffeature {
+ name = "copymathscripts",
+ description = "copy math script",
+ prepend = 1,
+ initializers = {
+ base = initialize,
+ node = initialize,
+ }
+}
+
diff --git a/tex/context/base/mkxl/font-otl.lmt b/tex/context/base/mkxl/font-otl.lmt
index a68988e87..85b32470b 100644
--- a/tex/context/base/mkxl/font-otl.lmt
+++ b/tex/context/base/mkxl/font-otl.lmt
@@ -52,7 +52,7 @@ local report_otf = logs.reporter("fonts","otf loading")
local fonts = fonts
local otf = fonts.handlers.otf
-otf.version = 3.119 -- beware: also sync font-mis.lua and in mtx-fonts
+otf.version = 3.120 -- beware: also sync font-mis.lua and in mtx-fonts
otf.cache = containers.define("fonts", "otl", otf.version, true)
otf.svgcache = containers.define("fonts", "svg", otf.version, true)
otf.pngcache = containers.define("fonts", "png", otf.version, true)
diff --git a/tex/context/base/mkxl/libs-imp-zint.lmt b/tex/context/base/mkxl/libs-imp-zint.lmt
index 1b1d294c9..d8d882924 100644
--- a/tex/context/base/mkxl/libs-imp-zint.lmt
+++ b/tex/context/base/mkxl/libs-imp-zint.lmt
@@ -94,16 +94,12 @@ local shown = false
-- Same performance as just context(fmt,...): 113pps (On 2013 i7 laptop.)
--- ----- f_rectangle = formatters["%sofill unitsquare xysized (%N,%N) shifted (%N,%N);"]
--- local f_hexagon = formatters["%sofill (%N,%N)--(%N,%N)--(%N,%N)--(%N,%N)--(%N,%N)--(%N,%N)--cycle;"]
--- local f_circle = formatters["%sofill unitcircle scaled %N shifted (%N,%N);"]
-
----- f_rectangle = formatters["%nofill unitsquare xysized (%N,%N) shifted (%N,%N);"]
-local f_hexagon = formatters["%nofill (%N,%N)--(%N,%N)--(%N,%N)--(%N,%N)--(%N,%N)--(%N,%N)--cycle;"]
-local f_circle = formatters["%nofill unitcircle scaled %N shifted (%N,%N);"]
+local f_hexagon = formatters["%nofill (%N,-%N)--(%N,-%N)--(%N,-%N)--(%N,-%N)--(%N,-%N)--(%N,-%N)--cycle;"]
+local f_circle = formatters["%nofill unitcircle scaled %N shifted (%N,-%N);"]
local s_done = "dofill origin --cycle;"
-local f_string = formatters['draw textext("%s") scaled (%N/10) shifted (%N,%N);']
+local f_string = formatters['draw textext("%s") scaled (%N/10) shifted (%N,-%N);']
-- A bit faster: 130pps (When I see hexagons I'll do that too but MP takes way more time.)
@@ -116,8 +112,12 @@ local s_preamble = [[
save ns; def ns (expr a, b) = nofill unitsquare xyscaled a shifted b ; enddef;
]]
------ f_rectangle = formatters["%ss((%N,%N),(%N,%N));"]
-local f_rectangle = formatters["ns((%i,%i),(%i,%i));"]
+local f_rectangle = formatters["ns((%i,-%i),(%i,-%i));"]
+
+local aliases = {
+ isbnx = "isbn",
+ ISBNX = "ISBN",
+}
local function execute(specification)
if okay() then
@@ -130,11 +130,13 @@ local function execute(specification)
end
specification.option = option
--
- if lower(code) == "isbn" then
- specification.text = text and gsub(text,"[^%d]","") or ""
- end
- --
if code then
+ code = aliases[code] or code
+ --
+ if lower(code) == "isbn" then
+ specification.text = text and gsub(text,"[^%d]","") or ""
+ end
+ --
local id = mapping[code]
if id then
specification.code = id
@@ -151,38 +153,26 @@ local function execute(specification)
local n = #rectangles
for i=1,n do
local r = rectangles[i]
- -- context("%sofill unitsquare xysized (%N,%N) shifted (%N,%N);",
--- rectangles[i] = f_rectangle(
--- i == n and "d" or "n",r[3],r[4],r[1],r[2]
--- )
-rectangles[i] = f_rectangle(r[3],r[4],r[1],r[2])
+ rectangles[i] = f_rectangle(r[3],r[4],r[1],r[2])
end
-rectangles[n+1] = s_done
+ rectangles[n+1] = s_done
context("% t",rectangles)
end
if hexagons then
local n = #hexagons
for i=1,n do
- -- context("%sofill (%N,%N)--(%N,%N)--(%N,%N)--(%N,%N)--(%N,%N)--(%N,%N)--cycle;",
--- hexagons[i] = f_hexagon(
--- i == n and "d" or "n",unpack(hexagons[i])
--- )
-hexagons[i] = f_hexagon(unpack(hexagons[i]))
+ hexagons[i] = f_hexagon(unpack(hexagons[i]))
end
-hexagons[n+1] = s_done
+ hexagons[n+1] = s_done
context("% t",hexagons)
end
if circles then
local n = #circles
for i=1,n do
local c = circles[i]
- -- context("%sofill unitcircle scaled %N shifted (%N,%N);",
--- circles[i] = f_circle(
--- i == n and "d" or "n",c[3],c[1],c[2]
--- )
-circles[i] = f_circle(c[3],c[1],c[2])
-circles[n+1] = s_done
+ circles[i] = f_circle(c[3],c[1],c[2])
end
+ circles[n+1] = s_done
context("% t",circles)
end
if strings then
@@ -191,9 +181,7 @@ circles[n+1] = s_done
for i=1,n do
local s = strings[i]
-- context('draw textext("%s") scaled (%N/10) shifted (%N,%N);',
- strings[i] = f_string(
- s[4],s[3],s[1],s[2]
- )
+ strings[i] = f_string(s[4],s[3],s[1],s[2])
end
context("% t",strings)
end
diff --git a/tex/context/base/mkxl/math-act.lmt b/tex/context/base/mkxl/math-act.lmt
index 7aeec184f..047a5cbc6 100644
--- a/tex/context/base/mkxl/math-act.lmt
+++ b/tex/context/base/mkxl/math-act.lmt
@@ -436,6 +436,93 @@ end
do
+ function mathtweaks.replacements(target,original,parameters)
+ local list = parameters.list
+ if list then
+ local targetcharacters = target.characters
+ local originalcharacters = original.characters
+ local unicodes = original.resources.unicodes
+ if unicodes then
+ local count = 0
+ for k, v in sortedhash(list) do
+ if type(v) == "string" then
+ v = unicodes[v]
+ end
+ if type(v) == "number" then
+ targetcharacters[k] = targetcharacters[v]
+ count = count + 1
+ end
+ end
+ if trace_tweaking and count > 0 then
+ report_mathtweak("%i permanent replacements",count)
+ end
+ end
+ end
+ end
+
+ function mathtweaks.substitutes(target,original,parameters)
+ local list = parameters.list
+ if list then
+ local targetcharacters = target.characters
+ local originalcharacters = original.characters
+ local getsubstitution = fonts.handlers.otf.getsubstitution
+ local count = 0
+ for k, v in sortedhash(list) do
+ local sub = getsubstitution(original,k,v,true)
+ if sub then
+ targetcharacters[k] = targetcharacters[sub]
+ count = count + 1
+ end
+ end
+ if trace_tweaking and count > 0 then
+ report_mathtweak("%i permanent substitutions",count)
+ end
+ end
+ end
+
+ mathtweaks.replace = mathtweaks.replacements
+ mathtweaks.substitute = mathtweaks.substitutes
+
+end
+
+do
+
+ -- What a mess ... should be a different alphabet.
+
+ local function expand(target,original,list,selector,feature)
+ if feature then
+ local getsubstitution = fonts.handlers.otf.getsubstitution
+ for _, char in next, list do
+ local variant = getsubstitution(original,char,feature,true)
+ if variant then
+ mathematics.addvariant(target,char,variant,selector)
+ end
+ end
+ else
+ for i, char in next, list do
+ mathematics.addvariant(target,char,0xFE800+i,selector)
+ end
+ end
+ end
+
+ function mathtweaks.variants(target,original,parameters)
+ local feature = parameters.feature
+ local selector = parameters.selector
+ local kind = parameters.kind
+ if kind == "script" then
+ if selector then
+ expand(target,original,mathematics.alphabets.sr.tf.lcletters,selector,feature)
+ expand(target,original,mathematics.alphabets.sr.tf.ucletters,selector,feature)
+ end
+ end
+ end
+
+ mathtweaks.variant = mathtweaks.variants
+
+end
+
+do
+
-- see changed hack in math-fbk
local copytable = table.copy
diff --git a/tex/context/base/mkxl/math-ali.mkxl b/tex/context/base/mkxl/math-ali.mkxl
index 6149d9be2..7329fed96 100644
--- a/tex/context/base/mkxl/math-ali.mkxl
+++ b/tex/context/base/mkxl/math-ali.mkxl
@@ -71,36 +71,81 @@
\etoksapp\scratchtoks{\the\t_math_align_b}}%
\etoksapp\scratchtoks{\the\t_math_align_c}}
+\def\math_eqalign_set_defaults
+ {\normalbaselines % hm, spacing ?
+ \mathsurround\zeropoint
+ \tabskip\zeropoint
+ \everycr\emptytoks}
+
+% \def\math_math_in_eqalign#1%
+% {\startforceddisplaymath
+% \tabskip\zeropoint
+% \everycr\emptytoks
+% {{}#1{}}% brrr we need to replace {}
+% \stopforceddisplaymath}
+
+% \def\math_text_in_eqalign#1%
+% {\startimath
+% \tabskip\zeropoint
+% \everycr\emptytoks
+% #1%
+% \stopimath}
+
\def\math_math_in_eqalign#1%
- {\startforceddisplaymath
+ {\mathbeginclass\mathordcode
+ \mathendclass \mathordcode
+ \startforceddisplaymath
\tabskip\zeropoint
\everycr\emptytoks
- {{}#1{}}%
+ #1%
\stopforceddisplaymath}
\def\math_text_in_eqalign#1%
- {\startimath
+ {\mathbeginclass\mathordcode
+ \mathendclass \mathordcode
+ \startimath
\tabskip\zeropoint
\everycr\emptytoks
#1%
\stopimath}
-\permanent\protected\def\eqalign#1% why no halign here, probably because of displaywidth
- {\emptyhbox % why no \dontleavehmode
- \mskip\thinmuskip
- \vcenter
- {\math_openup\displayopenupvalue % was: \openup\jot
- \mathsurround\zeropoint
- \ialign{%
- \strut
+% \permanent\protected\def\eqalign#1% why no halign here, probably because of displaywidth
+% {\emptyhbox % why no \dontleavehmode
+% \mskip\thinmuskip
+% \vcenter
+% {\math_openup\displayopenupvalue % was: \openup\jot
+% \mathsurround\zeropoint
+% \ialign{%
+% \strut
+% \hfil
+% \startforceddisplaymath{\aligncontent}\stopforceddisplaymath
+% \aligntab
+% \startforceddisplaymath{{}\aligncontent{}}\stopforceddisplaymath
+% \hfil\crcr
+% #1\crcr}%
+% }%
+% \mskip\thinmuskip}
+
+\permanent\protected\def\eqalign#1% rather plain, is this used at all ...
+ {\dontleavehmode
+ \mskip\thinmuskip\vcenter\bgroup % \vcenter \s!class \mathwrappercode \bgroup
+ \math_openup\displayopenupvalue
+ \mathsurround\zeropoint % \math_eqalign_set_defaults
+ \ialign
+ {\strut
\hfil
- \startforceddisplaymath{\aligncontent}\stopforceddisplaymath
+ \mathbeginclass\mathordcode
+ \mathendclass \mathordcode
+ \startforceddisplaymath\aligncontent\stopforceddisplaymath
\aligntab
- \startforceddisplaymath{{}\aligncontent{}}\stopforceddisplaymath
- \hfil\crcr
- #1\crcr}%
- }%
- \mskip\thinmuskip}
+ \mathbeginclass\mathordcode
+ \mathendclass \mathordcode
+ \startforceddisplaymath\aligncontent\stopforceddisplaymath
+ \hfil
+ \crcr
+ #1%
+ \crcr}%
+ \egroup\mskip\thinmuskip} % \egroup
% preamble is scanned for tabskips so we need the span to prevent an error message
@@ -491,16 +536,6 @@
\dostoptagged % finish cell
\dostarttagged\t!mtablecell\empty}
-% \def\math_left_of_eqalign
-% {\ifcsname\??mathalignmentvariant\number\c_math_eqalign_column\endcsname
-% \ifcase\lastnamedcs \or \relax \or \hfill \or \hfill \fi
-% \fi}
-
-% \def\math_right_of_eqalign
-% {\ifcsname\??mathalignmentvariant\number\c_math_eqalign_column\endcsname
-% \ifcase\lastnamedcs \or \hfill \or \relax \or \hfill \fi
-% \fi}
-
\def\math_left_of_eqalign
{\ifcsname\??mathalignmentvariant\number\c_math_eqalign_column\endcsname
\ifcase\lastnamedcs \or \relax \or \hfill \or \hfill \fi
@@ -537,17 +572,7 @@
\fi
\fi}
-% \def\math_eqalign_set_column#1% we could just add to the preamble (as with other alignments)
-% {\expandafter\chardef\csname\??mathalignmentvariant\number\c_math_eqalign_column\expandafter\expandafter\expandafter\endcsname
-% \ifcsname\??mathalignmentvariant#1\endcsname\lastnamedcs\else\zerocount\fi\relax}
-
-% \def\math_eqalign_set_column_indeed[#1:#2:#3]% we don't really check for all (so * will do too) ... yet
-% {\expandafter\chardef\csname\??mathalignmentvariant\number
-% \ifcstok{#2}\emptytoks\c_math_eqalign_column\orelse\ifchknum#1\or#1\else\zerocount\fi
-% \endcsname
-% \ifcsname\??mathalignmentvariant#2\endcsname\lastnamedcs\else\zerocount\fi\relax}
-
-\def\math_eqalign_set_column_indeed[#1:#2:#3]% we don't really check for all (so * will do too) ... yet
+\protected\def\math_eqalign_set_column_indeed[#1:#2:#3]% we don't really check for all (so * will do too) ... yet
{\ifcstok{#2}\emptytoks
% current counter
\orelse\ifchknum#1\or
@@ -555,12 +580,21 @@
\else
\c_math_eqalign_column\zerocount
\fi
- \chardef\csname\??mathalignmentvariant\number\c_math_eqalign_column\endcsname
- \ifcsname\??mathalignmentvariant#2\endcsname\lastnamedcs\else\zerocount\fi\relax}
+ \expandafter\integerdef\csname\??mathalignmentvariant\number\c_math_eqalign_column\endcsname
+ \ifcsname\??mathalignmentvariant#2\endcsname\lastnamedcs\else\zerocount\fi\relax}
\def\math_eqalign_set_column#1%
{\normalexpanded{\math_eqalign_set_column_indeed[#1::]}}
+\def\math_eqalign_set_columns_step
+ {\advance\c_math_eqalign_column\plusone
+ %\c_math_matrix_columns\c_math_eqalign_column
+ \math_eqalign_set_column}
+
+\def\math_eqalign_set_columns#1%
+ {\c_math_eqalign_column\zerocount
+ \rawprocesscommacommand[#1]\math_eqalign_set_columns_step}
+
\letcsname\??mathalignmentvariant\v!normal\endcsname\zerocount
\letcsname\??mathalignmentvariant\v!left \endcsname\plusone
\letcsname\??mathalignmentvariant\v!right \endcsname\plustwo
@@ -713,100 +747,13 @@
[\c!distance=\emwidth,
\c!strut=\v!yes, % new
%\c!numberdistance=2.5\emwidth,
- \c!numberdistance=\zeropoint, % pending an extension wrt placement (Aditya/Hans)
- \c!left={\left\{\mskip\thinmuskip},
- \c!right={\right.}]
+ \c!numberdistance=\zeropoint]
\appendtoks
\frozen\instance\protected\edefcsname\e!start\currentmathcases\endcsname{\math_cases_start[\currentmathcases]}%
\frozen\instance \defcsname \e!stop \currentmathcases\endcsname{\math_cases_stop}%
\to \everydefinemathcases
-% \permanent\protected\def\math_cases_NC_zero
-% {\math_cases_NC}
-%
-% \permanent\protected\def\math_cases_MC_zero
-% {\math_cases_NC
-% \ifmmode\else
-% \startimath
-% \enforced\let\math_cases_end_math\stopimath
-% \fi}
-%
-% \let\math_cases_end_math\relax
-%
-% \permanent\protected\def\math_cases_NR_zero
-% {\unskip
-% \math_cases_end_math
-% \aligntab
-% \global\enforced\let\math_cases_NC\math_cases_NC_first
-% \dodirectdoubleempty\math_cases_NR}
-%
-% \permanent\protected\def\math_cases_NC_first
-% {\global\enforced\let\math_cases_NC\math_cases_NC_second}
-%
-% \permanent\protected\def\math_cases_NC_second
-% {\math_cases_end_math\aligntab}
-%
-% \let\math_cases_NR\math_align_NR_generic
-%
-% \installmacrostack\math_cases_NC
-%
-% \let\math_cases_strut\relax
-%
-% \permanent\tolerant\protected\def\math_cases_start[#1]#*[#2]%
-% {\begingroup
-% \edef\currentmathcases{#1}%
-% \ifarguments\or\or
-% \setupcurrentmathcases[#2]%
-% \fi
-% \edef\p_strut{\mathcasesparameter\c!strut}%
-% \ifx\p_strut\v!yes
-% \enforced\let\math_cases_strut\strut
-% \else
-% \enforced\let\math_cases_strut\relax
-% \fi
-% \mathcasesparameter\c!left
-% \vcenter\bgroup
-% \push_macro_math_cases_NC
-% \enforced\let\MC\math_cases_MC_zero
-% \enforced\let\NR\math_cases_NR_zero
-% \enforced\let\TB\math_common_TB
-% \enforced\glet\math_cases_NC\math_cases_NC_first
-% \normalbaselines
-% \mathsurround\zeropoint
-% \everycr\emptytoks
-% \tabskip\zeropoint
-% \global\c_math_eqalign_column\plusone
-% \halign\bgroup
-% \startimath
-% \mathcasesparameter\c!style
-% \aligncontent
-% \stopimath
-% \hfil
-% \aligntab
-% \hskip\mathcasesparameter\c!distance\relax
-% \pop_macro_math_cases_NC
-% \math_cases_strut % looks better
-% \aligncontent
-% \hfil
-% \aligntab
-% \hskip\mathcasesparameter\c!numberdistance\relax
-% % \let\formuladistance\!!zeropoint
-% \span\math_text_in_eqalign{\aligncontent}%
-% \crcr} % todo: number
-%
-% % When we have just protected we get an extra row but we can no flag
-% % this as a proper alignment related command which means that uit gets
-% % expanded.
-%
-% \noaligned\permanent\protected\def\math_cases_stop
-% {\crcr
-% \egroup
-% \pop_macro_math_cases_NC
-% \egroup
-% \mathcasesparameter\c!right
-% \endgroup}
-
\let\math_cases_strut\relax
\newcount\c_math_cases_nc
@@ -875,17 +822,17 @@
\enforced\let\math_cases_strut\relax
\fi
\push_macro_c_math_cases_nc
+ \mathatom \s!class \mathwrappedcode \bgroup
\mathcasesparameter\c!left
+ %\startmathfenced[\mathcasesparameter\c!somekey]%
+ \mathatom \s!class \mathconstructcode \bgroup
\vcenter\bgroup
\enforced\let\MC\math_cases_NC
\enforced\let\NC\math_cases_NC
\enforced\let\NR\math_cases_NR
\enforced\let\TC\math_cases_TC
\enforced\let\TB\math_common_TB
- \normalbaselines
- \mathsurround\zeropoint
- \everycr\emptytoks
- \tabskip\zeropoint
+ \math_eqalign_set_defaults
\global\c_math_eqalign_column\plusone
\global\c_math_eqalign_row\plusone
\global\c_math_cases_nc\zerocount
@@ -909,18 +856,36 @@
{\crcr
\egroup
\egroup
+ \egroup
+ %\stopmathfenced
\mathcasesparameter\c!right
+ \egroup
\pop_macro_c_math_cases_nc
\endgroup}
+% \definemathfence [cases] [\c!left="007B,\c!right=\v!none]
+% \definemathfence [sesac] [\c!left=\v!none,\c!right="007D]
+
\definemathcases[cases]
\definemathcases[\v!mathcases]
+% This might become key=cases in the end:
+
+\setupmathcases
+% [cases]
+ [\c!left={\startmathfenced[cases]},
+ \c!right=\stopmathfenced]
+
+\definemathcases
+ [sesac]
+ [\c!left={\startmathfenced[sesac]},
+ \c!right=\stopmathfenced]
+
%D \startbuffer
%D \placeformula \startformula \startcases
-%D \NC 2 \NC $ y > 0 $ \NR
-%D \NC 7 \NC $ x = 7 $ \NR[+]
-%D \NC 4 \NC otherwise \NR
+%D \NC 2 \NC y > 0 \NR
+%D \NC 7 \NC x = 7 \NR[+]
+%D \NC 4 \TC otherwise \NR
%D \stopcases \stopformula
%D \stopbuffer
%D
@@ -928,9 +893,9 @@
%D
%D \startbuffer
%D \placeformula \startformula x \startcases
-%D \NC 2 \NC $ y > 0 $ \NR[+]
-%D \NC 7 \NC $ x = 7 $ \NR
-%D \NC 4 \NC otherwise \NR
+%D \NC 2 \NC y > 0 \NR[+]
+%D \NC 7 \NC x = 7 \NR
+%D \NC 4 \TC otherwise \NR
%D \stopcases \stopformula
%D \stopbuffer
%D
@@ -938,9 +903,9 @@
%D
%D \startbuffer
%D \placeformula \startformula \startcases
-%D \NC 2 \NC $ y > 0 $ \NR
-%D \NC 7 \NC $ x = 7 $ \NR
-%D \NC 4 \NC otherwise \NR
+%D \NC 2 \NC y > 0 \NR
+%D \NC 7 \NC x = 7 \NR
+%D \NC 4 \TC otherwise \NR
%D \stopcases \stopformula
%D \stopbuffer
%D
@@ -948,9 +913,9 @@
%D
%D \startbuffer
%D \placeformula \startformula x \startcases
-%D \NC 2 \NC $ y > 0 $ \NR
-%D \NC 7 \NC $ x = 7 $ \NR
-%D \NC 4 \NC otherwise \NR
+%D \NC 2 \NC y > 0 \NR
+%D \NC 7 \NC x = 7 \NR
+%D \NC 4 \TC otherwise \NR
%D \stopcases \stopformula
%D \stopbuffer
%D
@@ -991,13 +956,6 @@
{\dostoptagged
\dostoptagged}
-% \def\math_matrix_start_row
-% {\noalign{\global\c_math_eqalign_column\zerocount}%
-% \dostarttagged\t!mtablerow\empty}
-%
-% \def\math_matrix_stop_row
-% {\dostoptagged}
-
\def\math_matrix_start_row
{\beginlocalcontrol
\global\c_math_eqalign_column\zerocount
@@ -1120,12 +1078,6 @@
\permanent\protected\def\math_matrix_NC_yes{\global\setfalse\c_math_matrix_first}
\permanent\protected\def\math_matrix_NC_nop{\aligntab} % avoids lookahead
-% \def\math_matrix_stop_wrapup
-% {\crcr
-% \strut
-% \crcr
-% \noalign{\vskip-\struthtdp}}
-
\def\math_matrix_check_rule_step#1%
{\doifelsenumber{#1}
{\scratchdimen#1\d_math_eqalign_rulethickness}
@@ -1170,7 +1122,11 @@
\to \everymathmatrix
\def\math_matrix_start_processing
- {\dontleavehmode
+ {\ifmmode
+ \mathatom \s!class \mathwrappedcode
+ \else
+ \dontleavehmode
+ \fi
\bgroup
\tabskip\zeropoint
\math_matrix_pickup
@@ -1193,9 +1149,9 @@
\egroup
\math_matrix_stop_table
\egroup
- \mathmatrixleft
+ \mathmatrixleft % experimental hook
\math_matrix_finish_nextbox
- \mathmatrixright
+ \mathmatrixright % experimental hook
\egroup}
\let\math_matrix_strut \strut
@@ -1216,20 +1172,6 @@
% \edef\p_rulecolor{\mathmatrixparameter\c!rulecolor}
\edef\math_matrix_set_style{\mathmatrixparameter\c!style}}
-\def\math_matrix_set_defaults
- {\normalbaselines % hm, spacing ?
- \mathsurround\zeropoint
- \tabskip\zeropoint}
-
-\def\math_matrix_set_columns_step
- {\advance\c_math_eqalign_column\plusone
- %\c_math_matrix_columns\c_math_eqalign_column
- \math_eqalign_set_column}
-
-\def\math_matrix_set_columns
- {\c_math_eqalign_column\zerocount
- \rawprocesscommacommand[\mathmatrixparameter\c!align]\math_matrix_set_columns_step}
-
\newcount\c_math_eqalign_column_saved
\newcount\c_math_eqalign_row_saved
@@ -1244,8 +1186,8 @@
\edef\currentmathmatrix{#1}%
\setupcurrentmathmatrix[#2]%
\math_matrix_check_settings
- \math_matrix_set_defaults
- \math_matrix_set_columns
+ \math_eqalign_set_defaults
+ \math_eqalign_set_columns{\mathmatrixparameter\c!align}%
\math_matrix_start_processing}
\def\math_matrix_stop
@@ -1277,10 +1219,12 @@
\defcsname\??mathmatrixalignlocation\v!low \endcsname{\lower\dimexpr(\nextboxdp-\nextboxht)/2\relax}
\def\math_matrix_finish_nextbox
- {\begincsname\??mathmatrixalignlocation\mathmatrixparameter\c!location\endcsname\hbox\bgroup
+ {\scratchcounter\mathstyle\relax
+ \begincsname\??mathmatrixalignlocation\mathmatrixparameter\c!location\endcsname\hbox\bgroup
\normalstartimath
+ \Ustyle\scratchcounter
\mathmatrixparameter\c!left
- \vcenter{\box\nextbox}%
+ \mathatom \s!class \mathconstructcode {\vcenter{\box\nextbox}}% \was \vcenter
\mathmatrixparameter\c!right
\normalstopimath
\egroup}
@@ -1426,29 +1370,7 @@
\endgroup}
%D The following code is derived from Aditya's simplematrix prototype but adapted to
-%D regular mathmatrices:
-
-% We keep this as reference:
-%
-% \def\math_matrix_simple_row#1%
-% {\rawprocesscommalist[#1]\math_matrix_simple_col
-% \toksapp\scratchtoks{\NR}}
-%
-% \def\math_matrix_simple_col#1%
-% {\toksapp\scratchtoks{\NC#1}}
-%
-% \permanent\tolerant\protected\def\math_matrix_simple[#1]#*[#2]#:#3%
-% {\begingroup
-% \edef\currentmathmatrix{#1}%
-% \setupcurrentmathmatrix[#2]%
-% \scratchtoks\emptytoks
-% \processlist[];\math_matrix_simple_row[#3]%
-% \math_matrix_start[\currentmathmatrix]%
-% \the\scratchtoks
-% \math_matrix_stop
-% \endgroup}
-
-%D With a little help from \LUA\ we now have this:
+%D regular mathmatrices. With a little help from \LUA\ we now have this:
%D
%D \startbuffer
%D \definemathmatrix [Pmatrix] [matrix:parentheses]
@@ -1492,9 +1414,33 @@
%D And predefine some matrices:
-\definemathmatrix[matrix:parentheses][\c!left={\left(\mskip\thinmuskip},\c!right={\mskip\thinmuskip\right)},\c!align=\v!middle]
-\definemathmatrix[matrix:brackets] [\c!left={\left[\mskip\thinmuskip},\c!right={\mskip\thinmuskip\right]},\c!align=\v!middle]
-\definemathmatrix[matrix:bars] [\c!left={\left|\mskip\thinmuskip},\c!right={\mskip\thinmuskip\right|},\c!align=\v!middle]
+% \definemathmatrix[matrix:parentheses][\c!left={\left(\mskip\thinmuskip},\c!right={\mskip\thinmuskip\right)},\c!align=\v!middle]
+% \definemathmatrix[matrix:brackets] [\c!left={\left[\mskip\thinmuskip},\c!right={\mskip\thinmuskip\right]},\c!align=\v!middle]
+% \definemathmatrix[matrix:bars] [\c!left={\left|\mskip\thinmuskip},\c!right={\mskip\thinmuskip\right|},\c!align=\v!middle]
+
+\definemathmatrix
+ [matrix:brackets]
+ [\c!left={\startmathfenced[bracket]},
+ \c!right=\stopmathfenced,
+ \c!align=\v!middle]
+
+\definemathmatrix
+ [matrix:parentheses]
+ [\c!left={\startmathfenced[parenthesis]},
+ \c!right=\stopmathfenced,
+ \c!align=\v!middle]
+
+\definemathmatrix
+ [matrix:bars]
+ [\c!left={\startmathfenced[bar]},
+ \c!right=\stopmathfenced,
+ \c!align=\v!middle]
+
+\definemathmatrix
+ [matrix:braces]
+ [\c!left={\startmathfenced[brace]},
+ \c!right=\stopmathfenced,
+ \c!align=\v!middle]
\definemathmatrix[thematrix][matrix:parentheses][\c!simplecommand=thematrix]
@@ -1680,9 +1626,6 @@
\installcorenamespace{mathinnerstart}
\installcorenamespace{mathinnerstop}
-% \protected\def\startinnermath{\csname\??mathinnerstart\formulaparameter\c!align\endcsname}
-% \protected\def\stopinnermath {\csname\??mathinnerstop \formulaparameter\c!align\endcsname}
-
\permanent\protected\def\startinnermath{\expandnamespaceparameter\??mathinnerstart\formulaparameter\c!align\v!normal}
\permanent\protected\def\stopinnermath {\expandnamespaceparameter\??mathinnerstop \formulaparameter\c!align\v!normal}
@@ -2215,6 +2158,119 @@
\maththreshold\ifcsname\??maththreshold\p_threshold\endcsname\lastnamedcs\else\p_threshold\fi\relax
\to \everymath % \everyemathematics
+%D Here is simple alignment mechanism:
+
+\installcorenamespace{mathsimplealign}
+
+\installcommandhandler \??mathsimplealign {mathsimplealign} \??mathsimplealign
+
+\setupmathsimplealign
+ [\c!distance=\v!math,
+ \c!align=\v!all:\v!middle,
+ \c!textdistance=.25\emwidth]
+
+\appendtoks
+ \frozen\instance\protected\edefcsname\e!start\currentmathsimplealign\endcsname{\math_simplealign_start[\currentmathsimplealign]}%
+ \frozen\instance \defcsname \e!stop \currentmathsimplealign\endcsname{\math_simplealign_stop}%
+\to \everydefinemathsimplealign
+
+\permanent\protected\def\math_simplealign_NC
+ {\aligntab}
+
+\noaligned\tolerant\permanent\protected\def\math_simplealign_NR[#1]#*[#2]%
+ {\unskip
+ \math_align_NR_generic[#1][#2]}
+
+\permanent\tolerant\protected\def\math_simplealign_start[#1]#*[#2]%
+ {\begingroup
+ \edef\currentmathsimplealign{#1}%
+ \ifarguments\or\or
+ \setupcurrentmathsimplealign[#2]%
+ \fi
+ \mathatom \s!class \mathwrappedcode \bgroup
+ \mathsimplealignparameter\c!left
+ %\startmathfenced[\mathsimplealignparameter\c!somekey]%
+ \mathatom \s!class \mathconstructcode \bgroup
+ \vcenter\bgroup
+ \enforced\let\MC\math_simplealign_NC
+ \enforced\let\NC\math_simplealign_NC
+ \enforced\let\NR\math_simplealign_NR
+ \enforced\let\TB\math_common_TB
+ \math_eqalign_set_defaults
+ \math_eqalign_set_columns{\mathsimplealignparameter\c!align}%
+ \global\c_math_eqalign_column\zerocount
+ \global\c_math_eqalign_row\plusone
+ \edef\m_simplealign_distance{\mathsimplealignparameter\c!distance}%
+ \halign\bgroup
+ \global\c_math_eqalign_column\zerocount
+ \global\advance\c_math_eqalign_row\zerocount
+ \ignorespaces
+ \aligncontent % dummy
+ \removeunwantedspaces
+ \aligntab
+ \global\advance\c_math_eqalign_column\plusone
+ \math_left_of_eqalign % \hfil
+ \ignorespaces
+ \startimath
+ \aligncontent
+ \stopimath
+ \removeunwantedspaces
+ \math_right_of_eqalign % \hfil
+ \aligntab
+ \aligntab
+ \global\advance\c_math_eqalign_column\plusone
+ \math_left_of_eqalign % \hfil
+ \ifx\m_simplealign_distance\v!math
+ \mathbeginclass\lastrightclass
+ \else
+ \kern\m_simplealign_distance
+ \fi
+ \ignorespaces
+ \startimath
+ \aligncontent
+ \stopimath
+ \removeunwantedspaces
+ \math_right_of_eqalign % \hfil
+ \crcr}
+
+\noaligned\permanent\protected\def\math_simplealign_stop
+ {\crcr
+ \egroup
+ \egroup
+ \egroup
+ %\stopmathfenced
+ \mathsimplealignparameter\c!right
+ \setbox\scratchbox\hbox{\mathsimplealignparameter\c!text}%
+ \ifvoid\scratchbox\else
+ \hskip\mathsimplealignparameter\c!textdistance
+ \vcenter{\box\scratchbox}%
+ \fi
+ \egroup
+ \endgroup}
+
+%D It's not that spectacular apart from spacing being proper inter atom spacing
+%D using one of the new \LUAMETATEX\ mechanisms.
+%D
+%D \starttyping
+%D \definemathsimplealign
+%D [whatever]
+%D [left={\startmathfenced[sesac]},
+%D right=\stopmathfenced]
+%D
+%D % distance=math,
+%D % distance=\zeropoint,
+%D % distance=1cm,
+%D % align={all:left}]
+%D
+%D \startformula
+%D \startwhatever[text=simple]
+%D \NC x \NC = \NC r \NC \cos\theta \NR
+%D \NC y \NC = \NC \frac{1}{2} \NC \sin\theta \NR
+%D \NC 9 \NC = \NC 123 \NC \sin\theta \NR
+%D \stopwhatever
+%D \stopformula
+%D \stoptyping
+
\protect \endinput
% \placeformula \startformula[-] \startmatrix
diff --git a/tex/context/base/mkxl/math-fen.mkxl b/tex/context/base/mkxl/math-fen.mkxl
index 08891286e..bd51abe20 100644
--- a/tex/context/base/mkxl/math-fen.mkxl
+++ b/tex/context/base/mkxl/math-fen.mkxl
@@ -141,7 +141,7 @@
\s!axis
\s!exact}
-\permanent\def\math_fenced_common#1#2#3#4% \Uwhatever class symbol source
+\def\math_fenced_common#1#2#3#4% \Uwhatever class symbol source
{\ifconditional\c_math_fenced_sized
\orelse\ifconditional\c_math_fenced_level_mode
\ifnum#2=\mathopencode
@@ -187,10 +187,19 @@
\math_fenced_common_factor_unknown
\fi
\usedcolorparameterattributes{\mathfenceparameter\c!color}%
- \s!class\ifempty\p_mathclass#2\else\p_mathclass\fi
- \s!source\numexpr\namedboxanchor{\mathfenceparameter#4}\relax
+ \s!class
+ \ifx\p_fence\v!none
+ \mathghostcode
+ \else
+ \ifempty\p_mathclass#2\else\p_mathclass\fi
+ \fi
+ \s!source
+ \numexpr\namedboxanchor{\mathfenceparameter#4}\relax
\math_fenced_trace
- \Udelimiter#2\fam\p_fence\relax
+ \Udelimiter
+ \mathghostcode
+ \fam
+ \ifx\p_fence\v!none\zerocount\else\p_fence\relax\fi
\fi
% we could use \s!attr \c_math_fenced_stack here
\ifconditional\c_math_fenced_sized
@@ -311,6 +320,21 @@
\enforced\let\fenced\math_fenced_direct
\to \everymathematics
+\permanent\tolerant\protected\def\startmathfenced[#1]#*[#2]%
+ {\begingroup
+ \def\currentmathfence{#1}%
+ \setupcurrentmathfence[#2]%
+ \math_fenced_fenced_start{#1}}
+
+\permanent\protected\def\stopmathfenced
+ {\math_fenced_fenced_stop\currentmathfence
+ \endgroup}
+
+% cases are defined in math-ali:
+
+\definemathfence [cases] [\c!left="007B,\c!right=\v!none]
+\definemathfence [sesac] [\c!left=\v!none,\c!right="007D]
+
%D This is new:
%D
%D \starttyping
diff --git a/tex/context/base/mkxl/math-ini.lmt b/tex/context/base/mkxl/math-ini.lmt
index f41170a97..b12c81086 100644
--- a/tex/context/base/mkxl/math-ini.lmt
+++ b/tex/context/base/mkxl/math-ini.lmt
@@ -129,10 +129,14 @@ local function_class = registerengineclass("function","fnc")
local digit_class = registerengineclass("digit","dig")
local division_class = registerengineclass("division","div")
local factorial_class = registerengineclass("factorial","fac")
+local wrapped_class = registerengineclass("wrapped", "wra")
+local construct_class = registerengineclass("construct", "con")
classes["begin"] = 62 classnames[62] = "begin"
classes["end"] = 63 classnames[63] = "end"
+callback.register("get_noad_class", function(n) return classnames[n] end)
+
local function registerprivateclass(name)
local class = classes[name]
if not class then
diff --git a/tex/context/base/mkxl/math-ini.mkxl b/tex/context/base/mkxl/math-ini.mkxl
index fbfc7a972..fceedb21e 100644
--- a/tex/context/base/mkxl/math-ini.mkxl
+++ b/tex/context/base/mkxl/math-ini.mkxl
@@ -167,6 +167,8 @@
\setnewconstant\mathexplicitcode \mathclassvalue explicit
\setnewconstant\mathdivisioncode \mathclassvalue division
\setnewconstant\mathfactorialcode \mathclassvalue factorial
+\setnewconstant\mathwrappedcode \mathclassvalue wrapped
+\setnewconstant\mathconstructcode \mathclassvalue construct
\setnewconstant\mathbegincode \mathclassvalue begin
\setnewconstant\mathendcode \mathclassvalue end
@@ -190,6 +192,9 @@
\copymathspacing \mathfunctioncode \mathordinarycode
\copymathspacing \mathdigitcode \mathordinarycode
+\copymathspacing \mathconstructcode \mathinnercode
+\copymathspacing \mathwrappedcode \mathfractioncode
+
\setnewconstant\mathlimopcode \plusone
\setnewconstant\mathnolopcode \plusone
@@ -212,7 +217,7 @@
% \newcount\relpenalty
% \newcount\prerelpenalty
-% topaccent botaccent .. but do we ever need these
+% topaccent botaccent .. but do we ever need these so they will be inlined or we need them for all
\permanent\protected\def\ordordspacing {\setmathspacing \mathordinarycode \mathordinarycode }
\permanent\protected\def\ordopspacing {\setmathspacing \mathordinarycode \mathoperatorcode }
@@ -453,6 +458,7 @@
\definesystemattribute[mathdomain] [public]
\definesystemattribute[mathcollapsing] [public]
\definesystemattribute[mathunstack] [public]
+\definesystemattribute[mathvariant] [public]
\definesystemattribute[displaymath] [public]
@@ -843,7 +849,7 @@
\inherited\punctordspacing \allscriptstyles\tinymuskip
\inherited\punctopspacing \allsplitstyles \thinmuskip
\inherited\punctopspacing \allscriptstyles\tinymuskip
- %% \inherited\punctbinspacing \allmathstyles \zeromuskip
+ % \inherited\punctbinspacing \allmathstyles \zeromuskip
\inherited\punctrelspacing \allsplitstyles \thinmuskip
\inherited\punctrelspacing \allscriptstyles\tinymuskip
\inherited\punctopenspacing \allsplitstyles \thinmuskip
@@ -926,14 +932,17 @@
\inherited\middleinnerspacing \allscriptstyles\tinymuskip
\inherited\middlefracspacing \allsplitstyles \medmuskip
\inherited\middlefracspacing \allscriptstyles\tinymuskip
- % \inherited\middleradspacing \allmathstyles \zeromuskip
+ % \inherited\middleradspacing \allmathstyles \zeromuskip
+ %
+ \inherited\setmathspacing \mathclosecode \mathdifferentialcode \allsplitstyles \thinmuskip
+ \inherited\setmathspacing \mathclosecode \mathdifferentialcode \allscriptstyles \tinymuskip
+ \inherited\setmathspacing \mathordinarycode \mathdifferentialcode \allsplitstyles \thinmuskip
+ \inherited\setmathspacing \mathordinarycode \mathdifferentialcode \allscriptstyles \tinymuskip
+ \inherited\setmathspacing \mathfactorialcode \mathordinarycode \allsplitstyles \thinmuskip
+ \inherited\setmathspacing \mathfactorialcode \mathordinarycode \allscriptstyles \tinymuskip
%
- \inherited\setmathspacing \mathclosecode \mathdifferentialcode \allsplitstyles \thinmuskip
- \inherited\setmathspacing \mathclosecode \mathdifferentialcode \allscriptstyles \tinymuskip
- \inherited\setmathspacing \mathordinarycode \mathdifferentialcode \allsplitstyles \thinmuskip
- \inherited\setmathspacing \mathordinarycode \mathdifferentialcode \allscriptstyles \tinymuskip
- \inherited\setmathspacing \mathfactorialcode \mathordinarycode \allsplitstyles \thinmuskip
- \inherited\setmathspacing \mathfactorialcode \mathordinarycode \allscriptstyles \tinymuskip
+ \inherited\setmathspacing \mathopencode \mathconstructcode \allmathstyles \thinmuskip
+ \inherited\setmathspacing \mathconstructcode \mathclosecode \allmathstyles \thinmuskip
\stopsetups
\directsetup{math:spacing:default}
@@ -1027,35 +1036,19 @@
\aliased\let\setmathfontstylealternative\setmathfontstylealternate
\aliased\let\mathalternate \setmathfontalternate
-% \permanent\protected\def\mathupright {\setmathattribute\s!regular\s!tf\setmathfontstylealternate\s!tf}
-% \permanent\protected\def\mathitalic {\setmathattribute\s!regular\s!it\setmathfontstylealternate\s!it}
-% \permanent\protected\def\mathscript {\setmathalphabet \s!script \setmathfontstylealternate\s!script}
-% \permanent\protected\def\mathfraktur {\setmathalphabet \s!fraktur \setmathfontstylealternate\s!fraktur}
-% \permanent\protected\def\mathblackboard{\setmathalphabet \s!blackboard\setmathfontstylealternate\s!blackboard}
+\permanent\protected\def\math_upright {\setmathattribute\s!regular\s!tf\setmathfontstylealternate\s!tf}
+\permanent\protected\def\math_italic {\setmathattribute\s!regular\s!it\setmathfontstylealternate\s!it}
+\permanent\protected\def\math_script {\setmathalphabet \s!script \setmathfontstylealternate\s!script\setmathvariant\s!handwriting}
+\permanent\protected\def\math_calligraphic{\setmathalphabet \s!script \setmathfontstylealternate\s!script\setmathvariant\s!calligraphy}
+\permanent\protected\def\math_fraktur {\setmathalphabet \s!fraktur \setmathfontstylealternate\s!fraktur}
+\permanent\protected\def\math_blackboard {\setmathalphabet \s!blackboard\setmathfontstylealternate\s!blackboard}
-\permanent\protected\def\math_upright {\setmathattribute\s!regular\s!tf\setmathfontstylealternate\s!tf}
-\permanent\protected\def\math_italic {\setmathattribute\s!regular\s!it\setmathfontstylealternate\s!it}
-\permanent\protected\def\math_script {\setmathalphabet \s!script \setmathfontstylealternate\s!script}
-\permanent\protected\def\math_fraktur {\setmathalphabet \s!fraktur \setmathfontstylealternate\s!fraktur}
-\permanent\protected\def\math_blackboard{\setmathalphabet \s!blackboard\setmathfontstylealternate\s!blackboard}
-
-\permanent\protected\def\mathupright {\mathgroupedcommandcs\math_upright}
-\permanent\protected\def\mathitalic {\mathgroupedcommandcs\math_italic}
-\permanent\protected\def\mathscript {\mathgroupedcommandcs\math_script}
-\permanent\protected\def\mathfraktur {\mathgroupedcommandcs\math_fraktur}
-\permanent\protected\def\mathblackboard{\mathgroupedcommandcs\math_blackboard}
-
-% \permanent\protected\def\mathrm{\setmathattribute\s!rm\s!tf\setmathfontstylealternate\s!tf}
-% \permanent\protected\def\mathss{\setmathattribute\s!ss\s!tf\setmathfontstylealternate\s!tf}
-% \permanent\protected\def\mathtt{\setmathattribute\s!tt\s!tf\setmathfontstylealternate\s!tf}
-%
-% \permanent\protected\def\mathtf{\setmathfontstyle\s!tf\setmathfontstylealternate\s!tf}
-% \permanent\protected\def\mathsl{\setmathfontstyle\s!it\setmathfontstylealternate\s!it} % no sl
-% \permanent\protected\def\mathit{\setmathfontstyle\s!it\setmathfontstylealternate\s!it}
-%
-% \permanent\protected\def\mathbf{\setmathfontstyle\s!bf\setmathfontstylealternate\s!bf}
-% \permanent\protected\def\mathbs{\setmathfontstyle\s!bi\setmathfontstylealternate\s!bi} % no sl
-% \permanent\protected\def\mathbi{\setmathfontstyle\s!bi\setmathfontstylealternate\s!bi}
+\permanent\protected\def\mathupright {\mathgroupedcommandcs\math_upright}
+\permanent\protected\def\mathitalic {\mathgroupedcommandcs\math_italic}
+\permanent\protected\def\mathscript {\mathgroupedcommandcs\math_script}
+\permanent\protected\def\mathcalligraphic{\mathgroupedcommandcs\math_calligraphic}
+\permanent\protected\def\mathfraktur {\mathgroupedcommandcs\math_fraktur}
+\permanent\protected\def\mathblackboard {\mathgroupedcommandcs\math_blackboard}
\permanent\protected\def\math_rm{\setmathattribute\s!rm\s!tf\setmathfontstylealternate\s!tf}
\permanent\protected\def\math_ss{\setmathattribute\s!ss\s!tf\setmathfontstylealternate\s!tf}
@@ -1108,16 +1101,17 @@
\aliased\let\Bbb\mathblackboard
-\permanent\protected\def\frak {\ifmmode\expandafter\mathfraktur \fi}
-\permanent\protected\def\cal {\ifmmode\expandafter\mathscript \fi}
-\permanent\protected\def\bbd {\ifmmode\expandafter\mathblackboard\fi}
-\permanent\protected\def\blackboard{\ifmmode\expandafter\mathblackboard\fi}
-\permanent\protected\def\fraktur {\ifmmode\expandafter\mathfraktur \fi}
-\permanent\protected\def\gothic {\ifmmode\expandafter\mathfraktur \fi}
-
-\permanent\protected\def\mathcal {\mathgroupedcommandcs\math_script \relax} % for AMS compatibility
-\permanent\protected\def\mathfrak{\mathgroupedcommandcs\math_fraktur \relax} % for AMS compatibility
-\permanent\protected\def\mathbb {\mathgroupedcommandcs\math_blackboard\relax} % for AMS compatibility
+\permanent\protected\def\frak {\ifmmode\expandafter\mathfraktur \fi}
+\permanent\protected\def\cal {\ifmmode\expandafter\mathcalligraphic\fi}
+\permanent\protected\def\bbd {\ifmmode\expandafter\mathblackboard \fi}
+\permanent\protected\def\blackboard{\ifmmode\expandafter\mathblackboard \fi}
+\permanent\protected\def\fraktur {\ifmmode\expandafter\mathfraktur \fi}
+\permanent\protected\def\gothic {\ifmmode\expandafter\mathfraktur \fi}
+
+\permanent\protected\def\mathcal {\mathgroupedcommandcs\math_calligraphic\relax} % for AMS compatibility
+\permanent\protected\def\mathscr {\mathgroupedcommandcs\math_script \relax} % for AMS compatibility
+\permanent\protected\def\mathfrak{\mathgroupedcommandcs\math_fraktur \relax} % for AMS compatibility
+\permanent\protected\def\mathbb {\mathgroupedcommandcs\math_blackboard \relax} % for AMS compatibility
\ifdefined\normaltf \else \permanent\let\normaltf\tf \fi \permanent\protected\def\tf{\ifmmode\expandafter\mathtf\else\expandafter\normaltf\fi}
\ifdefined\normalbf \else \permanent\let\normalbf\bf \fi \permanent\protected\def\bf{\ifmmode\expandafter\mathbf\else\expandafter\normalbf\fi}
diff --git a/tex/context/base/mkxl/math-noa.lmt b/tex/context/base/mkxl/math-noa.lmt
index e035a9f68..02f425542 100644
--- a/tex/context/base/mkxl/math-noa.lmt
+++ b/tex/context/base/mkxl/math-noa.lmt
@@ -458,7 +458,15 @@ local checked = { } -- simple case
local tracked = false trackers.register("fonts.missing", function(v) tracked = v end)
local cached = setmetatableindex("table") -- complex case
+local variantselectors = {
+ [0xFE00] = true,
+ [0xFE01] = true
+}
+
local function errorchar(font,char)
+ if variantselectors[char] then
+ return char
+ end
local done = unknowns[char]
if done then
unknowns[char] = done + 1
@@ -1810,7 +1818,7 @@ end
do
- -- is validpair stil needed?
+ -- is validpair stil needed? why not always now?
local a_mathcollapsing = privateattribute("mathcollapsing")
local collapse = { }
@@ -2011,61 +2019,86 @@ do
end
--- variants
+-- variants (upgraded for script too)
do
- local variants = { }
- local validvariants = { -- fast check on valid
- [0x2229] = 0xFE00, [0x222A] = 0xFE00,
- [0x2268] = 0xFE00, [0x2269] = 0xFE00,
- [0x2272] = 0xFE00, [0x2273] = 0xFE00,
- [0x228A] = 0xFE00, [0x228B] = 0xFE00,
- [0x2293] = 0xFE00, [0x2294] = 0xFE00,
- [0x2295] = 0xFE00,
- [0x2297] = 0xFE00,
- [0x229C] = 0xFE00,
- [0x22DA] = 0xFE00, [0x22DB] = 0xFE00,
- [0x2A3C] = 0xFE00, [0x2A3D] = 0xFE00,
- [0x2A9D] = 0xFE00, [0x2A9E] = 0xFE00,
- [0x2AAC] = 0xFE00, [0x2AAD] = 0xFE00,
- [0x2ACB] = 0xFE00, [0x2ACC] = 0xFE00,
- }
+ local variants = { }
+ local chardata = characters.data
+ local a_variant = privateattribute("mathvariant")
+
+ local function setvariant(pointer,selector,char)
+ local tfmdata = fontdata[getfont(pointer)]
+ local mathvariants = tfmdata.resources.variants -- and variantdata / can be a hash
+ if mathvariants then
+ mathvariants = mathvariants[selector]
+ if mathvariants then
+ local variant = mathvariants[char]
+ if variant then
+ setchar(pointer,variant)
+ setattr(pointer,a_exportstatus,char) -- we don't export the variant as it's visual markup
+ if trace_variants then
+ report_variants("variant (%U,%U) replaced by %U",char,selector,variant)
+ end
+ else
+ if trace_variants then
+ report_variants("no variant (%U,%U)",char,selector)
+ end
+ end
+ end
+ end
+ end
variants[mathchar_code] = function(pointer,what,n,parent) -- also set export value
local char = getchar(pointer)
- local selector = validvariants[char]
- if selector then
- local next = getnext(parent)
- if next and getid(next) == noad_code then
- local nucleus = getnucleus(next)
- if nucleus and getid(nucleus) == mathchar_code and getchar(nucleus) == selector then
- local variant
- local tfmdata = fontdata[getfont(pointer)]
- local mathvariants = tfmdata.resources.variants -- and variantdata
- if mathvariants then
- mathvariants = mathvariants[selector]
- if mathvariants then
- variant = mathvariants[char]
+ local data = chardata[char]
+ if data then
+ local variants = data.variants
+ if variants then
+ local next = getnext(parent)
+ if next and getid(next) == noad_code then
+ local nucleus = getnucleus(next)
+ if nucleus and getid(nucleus) == mathchar_code then
+ local selector = getchar(nucleus)
+ if variants[selector] then
+ setvariant(pointer,selector,char)
+ setprev(next,pointer)
+ setnext(parent,getnext(next))
+ flushnode(next)
end
end
- if variant then
- setchar(pointer,variant)
- setattr(pointer,a_exportstatus,char) -- we don't export the variant as it's visual markup
- if trace_variants then
- report_variants("variant (%U,%U) replaced by %U",char,selector,variant)
- end
- else
- if trace_variants then
- report_variants("no variant (%U,%U)",char,selector)
- end
+ end
+ local selector = getattr(pointer,a_variant)
+ if selector and variants[selector] then
+ setvariant(pointer,selector,char)
+ end
+ end
+ end
+ end
+
+ function mathematics.addvariant(tfmdata,char,variant,selector)
+ if char and variant and selector then
+ local data = chardata[char]
+ if data then
+ local variants = data.variants
+ if variants and variants[selector] then
+ local resources = tfmdata.resources
+ local variants = resources.variants -- and variantdata
+ if not variants then
+ variants = { }
+ resources.variants = variants
end
- setprev(next,pointer)
- setnext(parent,getnext(next))
- flushnode(next)
+ local selectors = variants[selector]
+ if not selectors then
+ selectors = { }
+ variants[selector] = selectors
+ end
+ selectors[char] = variant
+ return true
end
end
end
+ return false
end
function handlers.variants(head,style,penalties)
@@ -2073,6 +2106,25 @@ do
return true -- not needed
end
+ local valid = {
+ calligraphic = 0xFE00,
+ calligraphy = 0xFE00,
+ script = 0xFE01,
+ handwriting = 0xFE01,
+ }
+
+ function mathematics.setvariant(s)
+ texsetattribute(a_variant,valid[s] or unsetvalue)
+ end
+
+ implement {
+ name = "setmathvariant",
+ public = true,
+ protected = true,
+ arguments = "string",
+ actions = mathematics.setvariant,
+ }
+
end
-- for manuals
@@ -2335,9 +2387,9 @@ local actions = tasks.actions("math") -- head, style, penalties
local starttiming, stoptiming = statistics.starttiming, statistics.stoptiming
-function processors.mlisttohlist(head,style,penalties)
+function processors.mlisttohlist(head,style,penalties,beginclass,endclass)
starttiming(noads)
- head = actions(head,style,penalties)
+ head = actions(head,style,penalties,beginclass,endclass)
stoptiming(noads)
return head
end
diff --git a/tex/context/base/mkxl/meta-ini.mkxl b/tex/context/base/mkxl/meta-ini.mkxl
index 6ddf4def8..82cf516c2 100644
--- a/tex/context/base/mkxl/meta-ini.mkxl
+++ b/tex/context/base/mkxl/meta-ini.mkxl
@@ -67,6 +67,8 @@
\newtoks \everyMPgraphic % mp % public or not ?
\appendtoks
+ \setcatcodetable\ctxcatcodes
+ % then this is not needed:
\restoreendofline % see interferences-001.tex
\to \everyMPgraphic
diff --git a/tex/context/base/mkxl/mlib-lmp.lmt b/tex/context/base/mkxl/mlib-lmp.lmt
index 01c72e4ba..3518f94bd 100644
--- a/tex/context/base/mkxl/mlib-lmp.lmt
+++ b/tex/context/base/mkxl/mlib-lmp.lmt
@@ -213,16 +213,34 @@ do
local hashes = table.setmetatableindex("table")
+ -- There is no need to 'new' a hash in which case one can use any reasonable
+ -- tag. The registry aproach is mkiv compatible.
+
+ local registery = { }
+
+ -- registerdirect("lmt_hash_new", function()
+ -- -- local name = scanstring()
+ -- local name = scanwhatever()
+ -- hashes[name] = { }
+ -- end)
+
registerdirect("lmt_hash_new", function()
- -- local name = scanstring()
- local name = scanwhatever()
- hashes[name] = { }
+ for i=1,#registry + 1 do
+ if not registry[i] then
+ registry[i] = { }
+ injectwhatever(i)
+ end
+ end
end)
registerdirect("lmt_hash_dispose", function()
-- local name = scanstring()
local name = scanwhatever()
hashes[name] = nil
+ -- when new'd
+ if registry[name] then
+ registry[name] = false
+ end
end)
registerdirect("lmt_hash_in", function()
@@ -349,6 +367,8 @@ do
local jobpositions = job.positions
local getwhd = jobpositions.whd
local getxy = jobpositions.xy
+ local getx = jobpositions.x
+ local gety = jobpositions.y
local getposition = jobpositions.position
local getpage = jobpositions.page
local getparagraph = jobpositions.paragraph
diff --git a/tex/context/base/mkxl/mlib-lua.lmt b/tex/context/base/mkxl/mlib-lua.lmt
index e40954456..005a57a72 100644
--- a/tex/context/base/mkxl/mlib-lua.lmt
+++ b/tex/context/base/mkxl/mlib-lua.lmt
@@ -109,7 +109,7 @@ inject.quadruplet = inject.cmykcolor
inject.whd = function(w,h,d) injectcolor (currentmpx,(w or 0)*bpfactor,(h or 0)*bpfactor,(d or 0)*bpfactor) end
inject.xy = function(x,y) injectpair (currentmpx,(x or 0)*bpfactor,(y or 0)*bpfactor) end
-inject.pt = function(n) injectnumeric(currentmpx,(x or 0)*bpfactor) end
+inject.pt = function(n) injectnumeric(currentmpx,(n or 0)*bpfactor) end
local function same(p,n)
local f = p[1]
diff --git a/tex/context/base/mkxl/node-tsk.lmt b/tex/context/base/mkxl/node-tsk.lmt
index c1cdf91a4..be4052258 100644
--- a/tex/context/base/mkxl/node-tsk.lmt
+++ b/tex/context/base/mkxl/node-tsk.lmt
@@ -917,7 +917,7 @@ local tonode = nodes.nuts.tonode
%localize%
-return function(head,style,penalties)
+return function(head,style,penalties,beginclass,endclass)
local nuthead = tonut(head)
%actions%
@@ -926,19 +926,19 @@ end
]],
step = [[
- nuthead = tonut((%action%(tonode(nuthead),style,penalties)))
+ nuthead = tonut((%action%(tonode(nuthead),style,penalties,beginclass,endclass)))
]],
nut = [[
- nuthead = %action%(nuthead,style,penalties)
+ nuthead = %action%(nuthead,style,penalties,beginclass,endclass)
]],
nohead = [[
- %action%(tonode(nuthead),style,penalties)
+ %action%(tonode(nuthead),style,penalties,beginclass,endclass)
]],
nonut = [[
- %action%(nuthead,style,penalties)
+ %action%(nuthead,style,penalties,beginclass,endclass)
]],
}
diff --git a/tex/context/base/mkxl/pack-box.mkxl b/tex/context/base/mkxl/pack-box.mkxl
index 831ec1707..bc73a80d7 100644
--- a/tex/context/base/mkxl/pack-box.mkxl
+++ b/tex/context/base/mkxl/pack-box.mkxl
@@ -1253,15 +1253,20 @@
\permanent\protected\def\defineboxanchor[#1]%
{\registerboxanchor
- \expandafter\integerdef\csname\??boxanchors#1\endcsname\registeredboxanchor}
+ \global\expandafter\integerdef\csname\??boxanchors#1\endcsname\registeredboxanchor}
\permanent\def\namedboxanchor#1%
{\normalexpanded{\ifcsname\??boxanchors#1\endcsname\lastnamedcs\orelse\ifchknum#1\or#1\else\zerocount\fi}}
+\permanent\def\namespacedboxanchor#1%
+ {boxanchor:\number\namedboxanchor{#1}}
+
\installcorenamespace{boxanchorcontent}
-\installparameterhandler \??boxanchorcontent {boxanchorcontent}
-\installsetuphandler \??boxanchorcontent {boxanchorcontent}
+% \installparameterhandler \??boxanchorcontent {boxanchorcontent}
+% \installautosetuphandler \??boxanchorcontent {boxanchorcontent}
+
+\installcommandhandler \??boxanchorcontent {boxanchorcontent} \??boxanchorcontent % no real need but let's have a define too
\setupboxanchorcontent
[\c!yoffset=\zeropoint,
@@ -1270,10 +1275,15 @@
\c!location=\v!height,
\c!corner=\v!depth]
-\permanent\tolerant\protected\def\setboxanchor[#1]#*[#2]#*% assumes \defineboxanchor[#1]
+\permanent\tolerant\protected\def\setboxanchor[#1]#*[#2]#*[#3]#*% assumes \defineboxanchor[#1]
{\begingroup
\dowithnextbox
- {\setupcurrentboxanchorcontent[#2]%
+ {\ifhastok={#2}%
+ \setupcurrentboxanchorcontent[#2]%
+ \else
+ \def\currentboxanchorcontent{#2}%
+ \setupcurrentboxanchorcontent[#3]%
+ \fi
\scratchxoffset\boxanchorcontentparameter\c!xoffset
\scratchyoffset\boxanchorcontentparameter\c!yoffset
\scratchcounter\namedboxanchor{#1}%
@@ -1290,6 +1300,10 @@
{\box\nextbox}%
\endgroup}}
+%D The name might change:
+
+\permanent\protected\def\mathboxanchored#1#2{#2\Umathsource\namedboxanchor{#1}\relax}
+
% to be used as:
%
% \scratchcounter\registeredboxanchor
diff --git a/tex/context/base/mkxl/pack-mat.mkxl b/tex/context/base/mkxl/pack-mat.mkxl
index c0aa1cc94..0c62638cb 100644
--- a/tex/context/base/mkxl/pack-mat.mkxl
+++ b/tex/context/base/mkxl/pack-mat.mkxl
@@ -30,7 +30,7 @@
\ifconditional\c_framed_math_framed
\defineboxanchor[temp]%
\fi
- \setmathatomrule\mathbegincode\mathbincode\allmathstyles\mathbegincode\mathbincode
+ \setmathatomrule\mathbegincode\mathbincode\allmathstyles\mathbegincode\mathbincode % hm
\normalexpanded
{\setbox\scratchbox\hpack
\ifconditional\c_framed_math_framed
diff --git a/tex/context/base/mkxl/page-one.mkxl b/tex/context/base/mkxl/page-one.mkxl
index f900d561d..c997557ef 100644
--- a/tex/context/base/mkxl/page-one.mkxl
+++ b/tex/context/base/mkxl/page-one.mkxl
@@ -440,9 +440,19 @@
\fi
\page_one_command_set_bottom_insertions_indeed}
+% \protected\def\page_one_command_flush_top_insertions
+% {\ifzeropt\page_inserts_get_height\namedinsertionnumber\s!topfloat\else
+% \page_one_command_flush_top_insertions_indeed % less tracing
+% \fi
+% \global\d_page_floats_inserted_top\zeropoint}
+
\protected\def\page_one_command_flush_top_insertions
{\ifzeropt\page_inserts_get_height\namedinsertionnumber\s!topfloat\else
\page_one_command_flush_top_insertions_indeed % less tracing
+ \ifcase\bottomraggednessmode\or\else
+ % will be an option
+ \vskip\zeropoint plus \openstrutdepth minus \openstrutdepth
+ \fi
\fi
\global\d_page_floats_inserted_top\zeropoint}
diff --git a/tex/context/base/mkxl/spac-ver.mkxl b/tex/context/base/mkxl/spac-ver.mkxl
index 68f74c9ee..be7b2bf5e 100644
--- a/tex/context/base/mkxl/spac-ver.mkxl
+++ b/tex/context/base/mkxl/spac-ver.mkxl
@@ -921,15 +921,15 @@
\permanent\protected\def\dosetstrut
{\enforced\let\strut\normalstrut
+ \struthtdp\dimexpr\strutht+\strutdp\relax
\ifabsnum\dimexpr\struthtdp-\lineheight\relax<\plustwo
% compensate rounding error /- 1sp to avoid too many
% 1sp baselineskips in for instance verbatim
% \strutht\dimexpr\lineheight-\strutdp\relax
% better:
\strutdp\dimexpr\lineheight-\strutht\relax
- \struttotal\lineheight
+ \struthtdp\lineheight
\fi
- \struthtdp\dimexpr\strutht+\strutdp\relax
\strutheight\strutht
\strutdepth \strutdp
\struttotal \struthtdp}
@@ -1063,6 +1063,7 @@
{\the\everysetnostrut}
\appendtoks
+ % \setbox\strutbox\copy\nostrutbox
\enforced\let\strut \empty
\enforced\let\endstrut\empty
\enforced\let\begstrut\empty
diff --git a/tex/context/base/mkxl/tabl-xtb.lmt b/tex/context/base/mkxl/tabl-xtb.lmt
new file mode 100644
index 000000000..32770141b
--- /dev/null
+++ b/tex/context/base/mkxl/tabl-xtb.lmt
@@ -0,0 +1,1310 @@
+if not modules then modules = { } end modules ['tabl-xtb'] = {
+ version = 1.001,
+ comment = "companion to tabl-xtb.mkvi",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+--[[
+
+This table mechanism is a combination between TeX and Lua. We do process
+cells at the TeX end and inspect them at the Lua end. After some analysis
+we have a second pass using the calculated widths, and if needed cells
+will go through a third pass to get the heights right. This last pass is
+avoided when possible which is why some code below looks a bit more
+complex than needed. The reason for such optimizations is that each cells
+is actually a framed instance and because tables like this can be hundreds
+of pages we want to keep processing time reasonable.
+
+To a large extend the behaviour is comparable with the way bTABLE/eTABLE
+works and there is a module that maps that one onto this one. Eventually
+this mechamism will be improved so that it can replace its older cousin.
+
+]]--
+
+-- todo: use linked list instead of r/c array
+-- todo: we can use the sum of previously forced widths for column spans
+
+local tonumber, next = tonumber, next
+
+local commands = commands
+local context = context
+local ctxnode = context.nodes.flush
+
+local implement = interfaces.implement
+
+local tex = tex
+local texgetcount = tex.getcount
+local texsetcount = tex.setcount
+local texgetdimen = tex.getdimen
+local texsetdimen = tex.setdimen
+local texget = tex.get
+
+local format = string.format
+local concat = table.concat
+local points = number.points
+
+local todimen = string.todimen
+
+local ctx_beginvbox = context.beginvbox
+local ctx_endvbox = context.endvbox
+local ctx_blank = context.blank
+local ctx_nointerlineskip = context.nointerlineskip
+local ctx_dummyxcell = context.dummyxcell
+
+local variables = interfaces.variables
+
+local setmetatableindex = table.setmetatableindex
+local settings_to_hash = utilities.parsers.settings_to_hash
+
+local nuts = nodes.nuts -- here nuts gain hardly nothing
+local tonut = nuts.tonut
+local tonode = nuts.tonode
+
+local getnext = nuts.getnext
+local getprev = nuts.getprev
+local getlist = nuts.getlist
+local getwidth = nuts.getwidth
+local getbox = nuts.getbox
+local getwhd = nuts.getwhd
+
+local setlink = nuts.setlink
+local setdirection = nuts.setdirection
+local setshift = nuts.setshift
+
+local copynodelist = nuts.copylist
+local hpacknodelist = nuts.hpack
+local flushnodelist = nuts.flushlist
+local takebox = nuts.takebox
+
+local nodepool = nuts.pool
+
+local new_glue = nodepool.glue
+local new_kern = nodepool.kern
+local new_hlist = nodepool.hlist
+
+local lefttoright_code = nodes.dirvalues.lefttoright
+
+local v_stretch = variables.stretch
+local v_normal = variables.normal
+local v_width = variables.width
+local v_height = variables.height
+local v_repeat = variables["repeat"]
+local v_max = variables.max
+local v_fixed = variables.fixed
+----- v_auto = variables.auto
+local v_before = variables.before
+local v_after = variables.after
+local v_both = variables.both
+local v_samepage = variables.samepage
+local v_tight = variables.tight
+
+local xtables = { }
+typesetters.xtables = xtables
+
+local trace_xtable = false
+local report_xtable = logs.reporter("xtable")
+
+trackers.register("xtable.construct", function(v) trace_xtable = v end)
+
+local null_mode = 0
+local head_mode = 1
+local foot_mode = 2
+local more_mode = 3
+local body_mode = 4
+
+local namedmodes = { [0] =
+ "null",
+ "head",
+ "foot",
+ "next",
+ "body",
+}
+
+local stack, data = { }, nil
+
+function xtables.create(settings)
+ table.insert(stack,data)
+ local rows = { }
+ local widths = { }
+ local heights = { }
+ local depths = { }
+ -- local spans = { }
+ local distances = { }
+ local autowidths = { }
+ local modes = { }
+ local fixedrows = { }
+ local fixedcolumns = { }
+ -- local fixedcspans = { }
+ local frozencolumns = { }
+ local options = { }
+ local rowproperties = { }
+ data = {
+ rows = rows,
+ widths = widths,
+ heights = heights,
+ depths = depths,
+ -- spans = spans,
+ distances = distances,
+ modes = modes,
+ autowidths = autowidths,
+ fixedrows = fixedrows,
+ fixedcolumns = fixedcolumns,
+ -- fixedcspans = fixedcspans,
+ frozencolumns = frozencolumns,
+ options = options,
+ nofrows = 0,
+ nofcolumns = 0,
+ currentrow = 0,
+ currentcolumn = 0,
+ settings = settings or { },
+ rowproperties = rowproperties,
+ }
+ local function add_zero(t,k)
+ t[k] = 0
+ return 0
+ end
+ local function add_table(t,k)
+ local v = { }
+ t[k] = v
+ return v
+ end
+ local function add_cell(row,c)
+ local cell = {
+ nx = 0,
+ ny = 0,
+ list = false,
+ wd = 0,
+ ht = 0,
+ dp = 0,
+ }
+ row[c] = cell
+ if c > data.nofcolumns then
+ data.nofcolumns = c
+ end
+ return cell
+ end
+ local function add_row(rows,r)
+ local row = { }
+ setmetatableindex(row,add_cell)
+ rows[r] = row
+ if r > data.nofrows then
+ data.nofrows = r
+ end
+ return row
+ end
+ setmetatableindex(rows,add_row)
+ setmetatableindex(widths,add_zero)
+ setmetatableindex(heights,add_zero)
+ setmetatableindex(depths,add_zero)
+ setmetatableindex(distances,add_zero)
+ setmetatableindex(modes,add_zero)
+ setmetatableindex(fixedrows,add_zero)
+ setmetatableindex(fixedcolumns,add_zero)
+ setmetatableindex(options,add_table)
+ -- setmetatableindex(fixedcspans,add_table)
+ --
+ local globaloptions = settings_to_hash(settings.option)
+ --
+ settings.columndistance = tonumber(settings.columndistance) or 0
+ settings.rowdistance = tonumber(settings.rowdistance) or 0
+ settings.leftmargindistance = tonumber(settings.leftmargindistance) or 0
+ settings.rightmargindistance = tonumber(settings.rightmargindistance) or 0
+ settings.options = globaloptions
+ settings.textwidth = tonumber(settings.textwidth) or texget("hsize")
+ settings.lineheight = tonumber(settings.lineheight) or texgetdimen("lineheight")
+ settings.maxwidth = tonumber(settings.maxwidth) or settings.textwidth/8
+ -- if #stack > 0 then
+ -- settings.textwidth = texget("hsize")
+ -- end
+ data.criterium_v = 2 * data.settings.lineheight
+ data.criterium_h = .75 * data.settings.textwidth
+ --
+ data.tight = globaloptions[v_tight] and true or false
+end
+
+function xtables.initialize_reflow_width(option,width)
+ local r = data.currentrow
+ local c = data.currentcolumn + 1
+ local drc = data.rows[r][c]
+ drc.nx = texgetcount("c_tabl_x_nx")
+ drc.ny = texgetcount("c_tabl_x_ny")
+ local distances = data.distances
+ local distance = texgetdimen("d_tabl_x_distance")
+ if distance > distances[c] then
+ distances[c] = distance
+ end
+ if option and option ~= "" then
+ local options = settings_to_hash(option)
+ data.options[r][c] = options
+ if options[v_fixed] then
+ data.frozencolumns[c] = true
+ end
+ end
+ data.currentcolumn = c
+end
+
+-- todo: we can better set the cell values in one go
+
+function xtables.set_reflow_width()
+ local r = data.currentrow
+ local c = data.currentcolumn
+ local rows = data.rows
+ local row = rows[r]
+ local cold = c
+ while row[c].span do -- can also be previous row ones
+ c = c + 1
+ end
+ -- bah, we can have a span already
+ if c > cold then
+ local ro = row[cold]
+ local rx = ro.nx
+ local ry = ro.ny
+ if rx > 1 or ry > 1 then
+ local rn = row[c]
+ rn.nx = rx
+ rn.ny = ry
+ ro.nx = 1 -- or 0
+ ro.ny = 1 -- or 0
+ -- do we also need to set ro.span and rn.span
+ end
+ end
+ local tb = getbox("b_tabl_x")
+ local drc = row[c]
+ --
+ drc.list = true -- we don't need to keep the content around as we're in trial mode (no: copynodelist(tb))
+ --
+ local width, height, depth = getwhd(tb)
+ --
+ local widths = data.widths
+ local heights = data.heights
+ local depths = data.depths
+ local cspan = drc.nx
+ if cspan < 2 then
+ if width > widths[c] then
+ widths[c] = width
+ end
+ else
+ local options = data.options[r][c]
+ if data.tight then
+ -- no check
+ elseif not options then
+ if width > widths[c] then
+ widths[c] = width
+ end
+ elseif not options[v_tight] then
+ if width > widths[c] then
+ widths[c] = width
+ end
+ end
+ end
+ -- if cspan > 1 then
+ -- local f = data.fixedcspans[c]
+ -- local w = f[cspan] or 0
+ -- if width > w then
+ -- f[cspan] = width -- maybe some day a solution for autospanmax and so
+ -- end
+ -- end
+ if drc.ny < 2 then
+ -- report_xtable("set width, old: ht=%p, dp=%p",heights[r],depths[r])
+ -- report_xtable("set width, new: ht=%p, dp=%p",height,depth)
+ if height > heights[r] then
+ heights[r] = height
+ end
+ if depth > depths[r] then
+ depths[r] = depth
+ end
+ end
+ --
+ drc.wd = width
+ drc.ht = height
+ drc.dp = depth
+ --
+ local dimensionstate = texgetcount("frameddimensionstate")
+ local fixedcolumns = data.fixedcolumns
+ local fixedrows = data.fixedrows
+ if dimensionstate == 1 then
+ if cspan > 1 then
+ -- ignore width
+ elseif width > fixedcolumns[c] then -- how about a span here?
+ fixedcolumns[c] = width
+ end
+ elseif dimensionstate == 2 then
+ fixedrows[r] = height
+ elseif dimensionstate == 3 then
+ fixedrows[r] = height -- width
+ fixedcolumns[c] = width -- height
+ elseif width <= data.criterium_h and height >= data.criterium_v then
+ -- somewhat tricky branch
+ if width > fixedcolumns[c] then -- how about a span here?
+ -- maybe an image, so let's fix
+ fixedcolumns[c] = width
+ end
+ end
+--
+-- -- this fails so not good enough predictor
+--
+-- -- \startxtable
+-- -- \startxrow
+-- -- \startxcell knuth \stopxcell
+-- -- \startxcell \input knuth \stopxcell
+-- -- \stopxrow
+--
+-- else
+-- local o = data.options[r][c]
+-- if o and o[v_auto] then -- new per 5/5/2014 - removed per 15/07/2014
+-- data.autowidths[c] = true
+-- else
+-- -- no dimensions are set in the cell
+-- if width <= data.criterium_h and height >= data.criterium_v then
+-- -- somewhat tricky branch
+-- if width > fixedcolumns[c] then -- how about a span here?
+-- -- maybe an image, so let's fix
+-- fixedcolumns[c] = width
+-- end
+-- else
+-- -- safeguard as it could be text that can be recalculated
+-- -- and the previous branch could have happened in a previous
+-- -- row and then forces a wrong one-liner in a multiliner
+-- if width > fixedcolumns[c] then
+-- data.autowidths[c] = true -- new per 5/5/2014 - removed per 15/07/2014
+-- end
+-- end
+-- end
+-- end
+--
+ --
+ drc.dimensionstate = dimensionstate
+ --
+ local nx = drc.nx
+ local ny = drc.ny
+ if nx > 1 or ny > 1 then
+ -- local spans = data.spans -- not used
+ local self = true
+ for y=1,ny do
+ for x=1,nx do
+ if self then
+ self = false
+ else
+ local ry = r + y - 1
+ local cx = c + x - 1
+ -- if y > 1 then
+ -- spans[ry] = true -- not used
+ -- end
+ rows[ry][cx].span = true
+ end
+ end
+ end
+ c = c + nx - 1
+ end
+ if c > data.nofcolumns then
+ data.nofcolumns = c
+ end
+ data.currentcolumn = c
+end
+
+function xtables.initialize_reflow_height()
+ local r = data.currentrow
+ local c = data.currentcolumn + 1
+ local rows = data.rows
+ local row = rows[r]
+ while row[c].span do -- can also be previous row ones
+ c = c + 1
+ end
+ data.currentcolumn = c
+ local widths = data.widths
+ local w = widths[c]
+ local drc = row[c]
+ for x=1,drc.nx-1 do
+ w = w + widths[c+x]
+ end
+ texsetdimen("d_tabl_x_width",w)
+ local dimensionstate = drc.dimensionstate or 0
+ if dimensionstate == 1 or dimensionstate == 3 then
+ -- width was fixed so height is known
+ texsetcount("c_tabl_x_skip_mode",1)
+ elseif dimensionstate == 2 then
+ -- height is enforced
+ texsetcount("c_tabl_x_skip_mode",1)
+ elseif data.autowidths[c] then
+ -- width has changed so we need to recalculate the height
+ texsetcount("c_tabl_x_skip_mode",0)
+ elseif data.fixedcolumns[c] then
+ texsetcount("c_tabl_x_skip_mode",0) -- new
+ else
+ texsetcount("c_tabl_x_skip_mode",1)
+ end
+end
+
+function xtables.set_reflow_height()
+ local r = data.currentrow
+ local c = data.currentcolumn
+ local rows = data.rows
+ local row = rows[r]
+ -- while row[c].span do -- we could adapt drc.nx instead
+ -- c = c + 1
+ -- end
+ local tb = getbox("b_tabl_x")
+ local drc = row[c]
+ --
+ local width, height, depth = getwhd(tb)
+ --
+ if drc.ny < 2 then
+ if data.fixedrows[r] == 0 then -- and drc.dimensionstate < 2
+ if drc.ht + drc.dp <= height + depth then -- new per 2017-12-15
+ local heights = data.heights
+ local depths = data.depths
+ -- report_xtable("set height, old: ht=%p, dp=%p",heights[r],depths[r])
+ -- report_xtable("set height, new: ht=%p, dp=%p",height,depth)
+ if height > heights[r] then
+ heights[r] = height
+ end
+ if depth > depths[r] then
+ depths[r] = depth
+ end
+ end
+ end
+ end
+ --
+ drc.wd = width
+ drc.ht = height
+ drc.dp = depth
+ --
+ -- c = c + drc.nx - 1
+ -- data.currentcolumn = c
+end
+
+function xtables.initialize_construct()
+ local r = data.currentrow
+ local c = data.currentcolumn + 1
+ local settings = data.settings
+ local rows = data.rows
+ local row = rows[r]
+ while row[c].span do -- can also be previous row ones
+ c = c + 1
+ end
+ data.currentcolumn = c
+ local widths = data.widths
+ local heights = data.heights
+ local depths = data.depths
+ local distances = data.distances
+ --
+ local drc = row[c]
+ local wd = drc.wd
+ local ht = drc.ht
+ local dp = drc.dp
+ local nx = drc.nx - 1
+ local ny = drc.ny - 1
+ --
+ local width = widths[c]
+ local height = heights[r]
+ local depth = depths[r] -- problem: can be the depth of a one liner
+ --
+ local total = height + depth
+ --
+ if nx > 0 then
+ for x=1,nx do
+ width = width + widths[c+x] + distances[c+x-1]
+ end
+ local distance = settings.columndistance
+ if distance ~= 0 then
+ width = width + nx * distance
+ end
+ end
+ --
+ if ny > 0 then
+ for y=1,ny do
+ local nxt = r + y
+ total = total + heights[nxt] + depths[nxt]
+ end
+ local distance = settings.rowdistance
+ if distance ~= 0 then
+ total = total + ny * distance
+ end
+ end
+ --
+ texsetdimen("d_tabl_x_width",width)
+ texsetdimen("d_tabl_x_height",total)
+ texsetdimen("d_tabl_x_depth",0) -- for now
+end
+
+function xtables.set_construct()
+ local r = data.currentrow
+ local c = data.currentcolumn
+ local rows = data.rows
+ local row = rows[r]
+ -- while row[c].span do -- can also be previous row ones
+ -- c = c + 1
+ -- end
+ local drc = row[c]
+ -- this will change as soon as in luatex we can reset a box list without freeing
+ drc.list = takebox("b_tabl_x")
+ -- c = c + drc.nx - 1
+ -- data.currentcolumn = c
+end
+
+local function showwidths(where,widths,autowidths)
+ local result = { }
+ for i=1,#widths do
+ result[#result+1] = format("%12s%s",points(widths[i]),autowidths[i] and "*" or " ")
+ end
+ return report_xtable("%s widths: %s",where,concat(result," "))
+end
+
+function xtables.reflow_width()
+ local nofrows = data.nofrows
+ local nofcolumns = data.nofcolumns
+ local rows = data.rows
+ for r=1,nofrows do
+ local row = rows[r]
+ for c=1,nofcolumns do
+ local drc = row[c]
+ if drc.list then
+ -- flushnodelist(drc.list)
+ drc.list = false
+ end
+ end
+ end
+ -- spread
+ local settings = data.settings
+ local options = settings.options
+ local maxwidth = settings.maxwidth
+ -- calculate width
+ local widths = data.widths
+ local heights = data.heights
+ local depths = data.depths
+ local distances = data.distances
+ local autowidths = data.autowidths
+ local fixedcolumns = data.fixedcolumns
+ local frozencolumns = data.frozencolumns
+ local width = 0
+ local distance = 0
+ local nofwide = 0
+ local widetotal = 0
+ local available = settings.textwidth - settings.leftmargindistance - settings.rightmargindistance
+ if trace_xtable then
+ showwidths("stage 1",widths,autowidths)
+ end
+ local noffrozen = 0
+ -- here we can also check spans
+ if options[v_max] then
+ for c=1,nofcolumns do
+ width = width + widths[c]
+ if width > maxwidth then
+ autowidths[c] = true
+ nofwide = nofwide + 1
+ widetotal = widetotal + widths[c]
+ end
+ if c < nofcolumns then
+ distance = distance + distances[c]
+ end
+ if frozencolumns[c] then
+ noffrozen = noffrozen + 1 -- brr, should be nx or so
+ end
+ end
+ else
+ for c=1,nofcolumns do -- also keep track of forced
+ local fixedwidth = fixedcolumns[c]
+ if fixedwidth > 0 then
+ widths[c] = fixedwidth
+ width = width + fixedwidth
+ else
+ local wc = widths[c]
+ width = width + wc
+ -- if width > maxwidth then
+ if wc > maxwidth then -- per 2015-08-09
+ autowidths[c] = true
+ nofwide = nofwide + 1
+ widetotal = widetotal + wc
+ end
+ end
+ if c < nofcolumns then
+ distance = distance + distances[c]
+ end
+ if frozencolumns[c] then
+ noffrozen = noffrozen + 1 -- brr, should be nx or so
+ end
+ end
+ end
+ if trace_xtable then
+ showwidths("stage 2",widths,autowidths)
+ end
+ local delta = available - width - distance - (nofcolumns-1) * settings.columndistance
+ if delta == 0 then
+ -- nothing to be done
+ if trace_xtable then
+ report_xtable("perfect fit")
+ end
+ elseif delta > 0 then
+ -- we can distribute some
+ if not options[v_stretch] then
+ -- not needed
+ if trace_xtable then
+ report_xtable("too wide but no stretch, delta %p",delta)
+ end
+ elseif options[v_width] then
+ local factor = delta / width
+ if trace_xtable then
+ report_xtable("proportional stretch, delta %p, width %p, factor %a",delta,width,factor)
+ end
+ for c=1,nofcolumns do
+ widths[c] = widths[c] + factor * widths[c]
+ end
+ else
+ -- frozen -> a column with option=fixed will not stretch
+ local extra = delta / (nofcolumns - noffrozen)
+ if trace_xtable then
+ report_xtable("normal stretch, delta %p, extra %p",delta,extra)
+ end
+ for c=1,nofcolumns do
+ if not frozencolumns[c] then
+ widths[c] = widths[c] + extra
+ end
+ end
+ end
+ elseif nofwide > 0 then
+ while true do
+ done = false
+ local available = (widetotal + delta) / nofwide
+ if trace_xtable then
+ report_xtable("shrink check, total %p, delta %p, columns %s, fixed %p",widetotal,delta,nofwide,available)
+ end
+ for c=1,nofcolumns do
+ if autowidths[c] and available >= widths[c] then
+ autowidths[c] = nil
+ nofwide = nofwide - 1
+ widetotal = widetotal - widths[c]
+ done = true
+ end
+ end
+ if not done then
+ break
+ end
+ end
+ -- maybe also options[v_width] here but tricky as width does not say
+ -- much about amount
+ if options[v_width] then -- not that much (we could have a clever vpack loop balancing .. no fun)
+ local factor = (widetotal + delta) / width
+ if trace_xtable then
+ report_xtable("proportional shrink used, total %p, delta %p, columns %s, factor %s",widetotal,delta,nofwide,factor)
+ end
+ for c=1,nofcolumns do
+ if autowidths[c] then
+ widths[c] = factor * widths[c]
+ end
+ end
+ else
+ local available = (widetotal + delta) / nofwide
+ if trace_xtable then
+ report_xtable("normal shrink used, total %p, delta %p, columns %s, fixed %p",widetotal,delta,nofwide,available)
+ end
+ for c=1,nofcolumns do
+ if autowidths[c] then
+ widths[c] = available
+ end
+ end
+ end
+ end
+ if trace_xtable then
+ showwidths("stage 3",widths,autowidths)
+ end
+ --
+ data.currentrow = 0
+ data.currentcolumn = 0
+end
+
+function xtables.reflow_height()
+ data.currentrow = 0
+ data.currentcolumn = 0
+ local settings = data.settings
+ --
+ -- analyze ny
+ --
+ local nofrows = data.nofrows
+ local nofcolumns = data.nofcolumns
+ local widths = data.widths
+ local heights = data.heights
+ local depths = data.depths
+ --
+ for r=1,nofrows do
+ for c=1,nofcolumns do
+ local drc = data.rows[r][c]
+ if drc then
+ local ny = drc.ny
+ if ny > 1 then
+ local height = heights[r]
+ local depth = depths[r]
+ local total = height + depth
+ local htdp = drc.ht + drc.dp
+ for y=1,ny-1 do
+ local nxt = r + y
+ total = total + heights[nxt] + depths[nxt]
+ end
+ local delta = htdp - total
+ if delta > 0 then
+ delta = delta / ny
+ for y=0,ny-1 do
+ local nxt = r + y
+ heights[nxt] = heights[nxt] + delta
+ end
+ end
+ end
+ end
+ end
+ end
+ --
+ if settings.options[v_height] then
+ local totalheight = 0
+ local totaldepth = 0
+ for i=1,nofrows do
+ totalheight = totalheight + heights[i]
+ totalheight = totalheight + depths [i]
+ end
+ local total = totalheight + totaldepth
+ local leftover = settings.textheight - total
+ if leftover > 0 then
+ local leftheight = (totalheight / total) * leftover / #heights
+ local leftdepth = (totaldepth / total) * leftover / #depths
+ for i=1,nofrows do
+ heights[i] = heights[i] + leftheight
+ depths [i] = depths [i] + leftdepth
+ end
+ end
+ end
+end
+
+local function showspans(data)
+ local rows = data.rows
+ local modes = data.modes
+ local nofcolumns = data.nofcolumns
+ local nofrows = data.nofrows
+ for r=1,nofrows do
+ local line = { }
+ local row = rows[r]
+ for c=1,nofcolumns do
+ local cell =row[c]
+ if cell.list then
+ line[#line+1] = "list"
+ elseif cell.span then
+ line[#line+1] = "span"
+ else
+ line[#line+1] = "none"
+ end
+ end
+ report_xtable("%3d : %s : % t",r,namedmodes[modes[r]] or "----",line)
+ end
+end
+
+function xtables.construct()
+ local rows = data.rows
+ local heights = data.heights
+ local depths = data.depths
+ local widths = data.widths
+ -- local spans = data.spans
+ local distances = data.distances
+ local modes = data.modes
+ local settings = data.settings
+ local nofcolumns = data.nofcolumns
+ local nofrows = data.nofrows
+ local columndistance = settings.columndistance
+ local rowdistance = settings.rowdistance
+ local leftmargindistance = settings.leftmargindistance
+ local rightmargindistance = settings.rightmargindistance
+ local rowproperties = data.rowproperties
+ -- ranges can be mixes so we collect
+
+ if trace_xtable then
+ showspans(data)
+ end
+
+ local ranges = {
+ [head_mode] = { },
+ [foot_mode] = { },
+ [more_mode] = { },
+ [body_mode] = { },
+ }
+ for r=1,nofrows do
+ local m = modes[r]
+ if m == 0 then
+ m = body_mode
+ end
+ local range = ranges[m]
+ range[#range+1] = r
+ end
+ -- todo: hook in the splitter ... the splitter can ask for a chunk of
+ -- a certain size ... no longer a split memory issue then and header
+ -- footer then has to happen here too .. target height
+ local function packaged_column(r)
+ local row = rows[r]
+ local start = nil
+ local stop = nil
+ if leftmargindistance > 0 then
+ start = new_kern(leftmargindistance)
+ stop = start
+ end
+ local hasspan = false
+ for c=1,nofcolumns do
+ local drc = row[c]
+ if not hasspan then
+ hasspan = drc.span
+ end
+ local list = drc.list
+ if list then
+ local w, h, d = getwhd(list)
+ setshift(list,h+d)
+ -- list = hpacknodelist(list) -- is somehow needed
+ -- setwhd(list,0,0,0)
+ -- faster:
+ local h = new_hlist(list)
+ list = h
+ --
+ if start then
+ setlink(stop,list)
+ else
+ start = list
+ end
+ stop = list
+ end
+ local step = widths[c]
+ if c < nofcolumns then
+ step = step + columndistance + distances[c]
+ end
+ local kern = new_kern(step)
+ if stop then
+ setlink(stop,kern)
+ else -- can be first spanning next row (ny=...)
+ start = kern
+ end
+ stop = kern
+ end
+ if start then
+ if rightmargindistance > 0 then
+ local kern = new_kern(rightmargindistance)
+ setlink(stop,kern)
+ -- stop = kern
+ end
+ return start, heights[r] + depths[r], hasspan
+ end
+ end
+ local function collect_range(range)
+ local result, nofr = { }, 0
+ local nofrange = #range
+ for i=1,#range do
+ local r = range[i]
+ -- local row = rows[r]
+ local list, size, hasspan = packaged_column(r)
+ if list then
+ if hasspan and nofr > 0 then
+ result[nofr][4] = true
+ end
+ nofr = nofr + 1
+ local rp = rowproperties[r]
+ -- we have a direction issue here but hpacknodelist(list,0,"exactly") cannot be used
+ -- due to the fact that we need the width
+ local hbox = hpacknodelist(list)
+ setdirection(hbox,lefttoright_code)
+ result[nofr] = {
+ hbox,
+ size,
+ i < nofrange and rowdistance > 0 and rowdistance or false, -- might move
+ false,
+ rp or false,
+ }
+ end
+ end
+ if nofr > 0 then
+ -- the [5] slot gets the after break
+ result[1] [5] = false
+ result[nofr][5] = false
+ for i=2,nofr-1 do
+ local r = result[i][5]
+ if r == v_both or r == v_before then
+ result[i-1][5] = true
+ elseif r == v_after then
+ result[i][5] = true
+ end
+ end
+ end
+ return result
+ end
+ local body = collect_range(ranges[body_mode])
+ data.results = {
+ [head_mode] = collect_range(ranges[head_mode]),
+ [foot_mode] = collect_range(ranges[foot_mode]),
+ [more_mode] = collect_range(ranges[more_mode]),
+ [body_mode] = body,
+ }
+ if #body == 0 then
+ texsetcount("global","c_tabl_x_state",0)
+ texsetdimen("global","d_tabl_x_final_width",0)
+ else
+ texsetcount("global","c_tabl_x_state",1)
+ texsetdimen("global","d_tabl_x_final_width",getwidth(body[1][1]))
+ end
+end
+
+-- todo: join as that is as efficient as fushing multiple
+
+local function inject(row,copy,package)
+ local list = row[1]
+ if copy then
+ row[1] = copynodelist(list)
+ end
+ if package then
+ ctx_beginvbox()
+ ctxnode(tonode(list))
+ ctxnode(tonode(new_kern(row[2])))
+ ctx_endvbox()
+ ctx_nointerlineskip() -- figure out a better way
+ if row[4] then
+ -- nothing as we have a span
+ elseif row[5] then
+ if row[3] then
+ ctx_blank { v_samepage, row[3] .. "sp" }
+ else
+ ctx_blank { v_samepage }
+ end
+ elseif row[3] then
+ ctx_blank { row[3] .. "sp" } -- why blank ?
+ else
+ ctxnode(tonode(new_glue(0)))
+ end
+ else
+ ctxnode(tonode(list))
+ ctxnode(tonode(new_kern(row[2])))
+ if row[3] then
+ ctxnode(tonode(new_glue(row[3])))
+ end
+ end
+end
+
+local function total(row,distance)
+ local n = #row > 0 and rowdistance or 0
+ for i=1,#row do
+ local ri = row[i]
+ n = n + ri[2] + (ri[3] or 0)
+ end
+ return n
+end
+
+-- local function append(list,what)
+-- for i=1,#what do
+-- local l = what[i]
+-- list[#list+1] = l[1]
+-- local k = l[2] + (l[3] or 0)
+-- if k ~= 0 then
+-- list[#list+1] = new_kern(k)
+-- end
+-- end
+-- end
+
+local function spanheight(body,i)
+ local height, n = 0, 1
+ while true do
+ local bi = body[i]
+ if bi then
+ height = height + bi[2] + (bi[3] or 0)
+ if bi[4] then
+ n = n + 1
+ i = i + 1
+ else
+ break
+ end
+ else
+ break
+ end
+ end
+ return height, n
+end
+
+function xtables.flush(directives) -- todo split by size / no inbetween then .. glue list kern blank
+ local height = directives.height
+ local method = directives.method or v_normal
+ local settings = data.settings
+ local results = data.results
+ local rowdistance = settings.rowdistance
+ local head = results[head_mode]
+ local foot = results[foot_mode]
+ local more = results[more_mode]
+ local body = results[body_mode]
+ local repeatheader = settings.header == v_repeat
+ local repeatfooter = settings.footer == v_repeat
+ if height and height > 0 then
+ ctx_beginvbox()
+ local bodystart = data.bodystart or 1
+ local bodystop = data.bodystop or #body
+ if bodystart > 0 and bodystart <= bodystop then
+ local bodysize = height
+ local footsize = total(foot,rowdistance)
+ local headsize = total(head,rowdistance)
+ local moresize = total(more,rowdistance)
+ local firstsize, firstspans = spanheight(body,bodystart)
+ if bodystart == 1 then -- first chunk gets head
+ bodysize = bodysize - headsize - footsize
+ if headsize > 0 and bodysize >= firstsize then
+ for i=1,#head do
+ inject(head[i],repeatheader)
+ end
+ if rowdistance > 0 then
+ ctxnode(tonode(new_glue(rowdistance)))
+ end
+ if not repeatheader then
+ results[head_mode] = { }
+ end
+ end
+ elseif moresize > 0 then -- following chunk gets next
+ bodysize = bodysize - footsize - moresize
+ if bodysize >= firstsize then
+ for i=1,#more do
+ inject(more[i],true)
+ end
+ if rowdistance > 0 then
+ ctxnode(tonode(new_glue(rowdistance)))
+ end
+ end
+ elseif headsize > 0 and repeatheader then -- following chunk gets head
+ bodysize = bodysize - footsize - headsize
+ if bodysize >= firstsize then
+ for i=1,#head do
+ inject(head[i],true)
+ end
+ if rowdistance > 0 then
+ ctxnode(tonode(new_glue(rowdistance)))
+ end
+ end
+ else -- following chunk gets nothing
+ bodysize = bodysize - footsize
+ end
+ if bodysize >= firstsize then
+ local i = bodystart
+ while i <= bodystop do -- room for improvement
+ local total, spans = spanheight(body,i)
+ local bs = bodysize - total
+ if bs > 0 then
+ bodysize = bs
+ for s=1,spans do
+ inject(body[i])
+ body[i] = nil
+ i = i + 1
+ end
+ bodystart = i
+ else
+ break
+ end
+ end
+ if bodystart > bodystop then
+ -- all is flushed and footer fits
+ if footsize > 0 then
+ if rowdistance > 0 then
+ ctxnode(tonode(new_glue(rowdistance)))
+ end
+ for i=1,#foot do
+ inject(foot[i])
+ end
+ results[foot_mode] = { }
+ end
+ results[body_mode] = { }
+ texsetcount("global","c_tabl_x_state",0)
+ else
+ -- some is left so footer is delayed
+ -- todo: try to flush a few more lines
+ if repeatfooter and footsize > 0 then
+ if rowdistance > 0 then
+ ctxnode(tonode(new_glue(rowdistance)))
+ end
+ for i=1,#foot do
+ inject(foot[i],true)
+ end
+ else
+ -- todo: try to fit more of body
+ end
+ texsetcount("global","c_tabl_x_state",2)
+ end
+ else
+ if firstsize > height then
+ -- get rid of the too large cell
+ for s=1,firstspans do
+ inject(body[bodystart])
+ body[bodystart] = nil
+ bodystart = bodystart + 1
+ end
+ end
+ texsetcount("global","c_tabl_x_state",2) -- 1
+ end
+ else
+ texsetcount("global","c_tabl_x_state",0)
+ end
+ data.bodystart = bodystart
+ data.bodystop = bodystop
+ ctx_endvbox()
+ else
+ if method == variables.split then
+ -- maybe also a non float mode with header/footer repeat although
+ -- we can also use a float without caption
+ for i=1,#head do
+ inject(head[i],false,true)
+ end
+ if #head > 0 and rowdistance > 0 then
+ ctx_blank { rowdistance .. "sp" }
+ end
+ for i=1,#body do
+ inject(body[i],false,true)
+ end
+ if #foot > 0 and rowdistance > 0 then
+ ctx_blank { rowdistance .. "sp" }
+ end
+ for i=1,#foot do
+ inject(foot[i],false,true)
+ end
+ else -- normal
+ ctx_beginvbox()
+ for i=1,#head do
+ inject(head[i])
+ end
+ if #head > 0 and rowdistance > 0 then
+ ctxnode(tonode(new_glue(rowdistance)))
+ end
+ for i=1,#body do
+ inject(body[i])
+ end
+ if #foot > 0 and rowdistance > 0 then
+ ctxnode(tonode(new_glue(rowdistance)))
+ end
+ for i=1,#foot do
+ inject(foot[i])
+ end
+ ctx_endvbox()
+ end
+ results[head_mode] = { }
+ results[body_mode] = { }
+ results[foot_mode] = { }
+ texsetcount("global","c_tabl_x_state",0)
+ end
+end
+
+function xtables.cleanup()
+ for mode, result in next, data.results do
+ for _, r in next, result do
+ flushnodelist(r[1])
+ end
+ end
+
+ -- local rows = data.rows
+ -- for i=1,#rows do
+ -- local row = rows[i]
+ -- for i=1,#row do
+ -- local cell = row[i]
+ -- local list = cell.list
+ -- if list then
+ -- cell.width, cell.height, cell.depth = getwhd(list)
+ -- cell.list = true
+ -- end
+ -- end
+ -- end
+ -- data.result = nil
+
+ data = table.remove(stack)
+end
+
+function xtables.next_row(specification)
+ local r = data.currentrow + 1
+ data.modes[r] = texgetcount("c_tabl_x_mode")
+ data.currentrow = r
+ data.currentcolumn = 0
+ data.rowproperties[r] = specification
+end
+
+function xtables.finish_row()
+ local c = data.currentcolumn
+ local r = data.currentrow
+ local d = data.rows[r][c]
+ local n = data.nofcolumns - c
+ if d then
+ local nx = d.nx
+ if nx > 0 then
+ n = n - nx + 1
+ end
+ end
+ if n > 0 then
+ for i=1,n do
+ ctx_dummyxcell()
+ end
+ end
+end
+
+-- eventually we might only have commands
+
+implement {
+ name = "x_table_create",
+ actions = xtables.create,
+ arguments = {
+ {
+ { "option" },
+ { "textwidth", "dimen" },
+ { "textheight", "dimen" },
+ { "maxwidth", "dimen" },
+ { "lineheight", "dimen" },
+ { "columndistance", "dimen" },
+ { "leftmargindistance", "dimen" },
+ { "rightmargindistance", "dimen" },
+ { "rowdistance", "dimen" },
+ { "header" },
+ { "footer" },
+ }
+ }
+}
+
+implement {
+ name = "x_table_flush",
+ actions = xtables.flush,
+ arguments = {
+ {
+ { "method" },
+ { "height", "dimen" }
+ }
+ }
+}
+
+implement { name = "x_table_reflow_width", actions = xtables.reflow_width }
+implement { name = "x_table_reflow_height", actions = xtables.reflow_height }
+implement { name = "x_table_construct", actions = xtables.construct }
+implement { name = "x_table_cleanup", actions = xtables.cleanup }
+implement { name = "x_table_next_row", actions = xtables.next_row }
+implement { name = "x_table_next_row_option", actions = xtables.next_row, arguments = "string" }
+implement { name = "x_table_finish_row", actions = xtables.finish_row }
+implement { name = "x_table_init_reflow_width", actions = xtables.initialize_reflow_width }
+implement { name = "x_table_init_reflow_height", actions = xtables.initialize_reflow_height }
+implement { name = "x_table_init_reflow_width_option", actions = xtables.initialize_reflow_width, arguments = "string" }
+implement { name = "x_table_init_reflow_height_option", actions = xtables.initialize_reflow_height, arguments = "string" }
+implement { name = "x_table_init_construct", actions = xtables.initialize_construct }
+implement { name = "x_table_set_reflow_width", actions = xtables.set_reflow_width }
+implement { name = "x_table_set_reflow_height", actions = xtables.set_reflow_height }
+implement { name = "x_table_set_construct", actions = xtables.set_construct }
+implement { name = "x_table_r", actions = function() context(data.currentrow or 0) end }
+implement { name = "x_table_c", actions = function() context(data.currentcolumn or 0) end }
+
+-- experiment:
+
+do
+
+ local context = context
+ local ctxcore = context.core
+
+ local startxtable = ctxcore.startxtable
+ local stopxtable = ctxcore.stopxtable
+
+ local startcollecting = context.startcollecting
+ local stopcollecting = context.stopcollecting
+
+ function ctxcore.startxtable(...)
+ startcollecting()
+ startxtable(...)
+ end
+
+ function ctxcore.stopxtable()
+ stopxtable()
+ stopcollecting()
+ end
+
+end
diff --git a/tex/context/base/mkxl/tabl-xtb.mklx b/tex/context/base/mkxl/tabl-xtb.mklx
index 5aad01884..ceea878da 100644
--- a/tex/context/base/mkxl/tabl-xtb.mklx
+++ b/tex/context/base/mkxl/tabl-xtb.mklx
@@ -15,7 +15,7 @@
\writestatus{loading}{ConTeXt Table Macros / Xtreme}
-\registerctxluafile{tabl-xtb}{}
+\registerctxluafile{tabl-xtb}{autosuffix}
% todo:
%
diff --git a/tex/context/base/mkxl/task-ini.lmt b/tex/context/base/mkxl/task-ini.lmt
index 7218f033f..eda40d356 100644
--- a/tex/context/base/mkxl/task-ini.lmt
+++ b/tex/context/base/mkxl/task-ini.lmt
@@ -100,8 +100,8 @@ appendaction("shipouts", "wrapup", "luatex.synctex.collect",
appendaction("math", "normalizers", "noads.handlers.showtree", nil, "nonut", "disabled" )
appendaction("math", "normalizers", "noads.handlers.unscript", nil, "nonut", "enabled" )
appendaction("math", "normalizers", "noads.handlers.unstack", nil, "nonut", "disabled" )
-appendaction("math", "normalizers", "noads.handlers.variants", nil, "nonut", "enabled" )
appendaction("math", "normalizers", "noads.handlers.relocate", nil, "nonut", "enabled" )
+appendaction("math", "normalizers", "noads.handlers.variants", nil, "nonut", "enabled" )
appendaction("math", "normalizers", "noads.handlers.families", nil, "nonut", "enabled" )
appendaction("math", "normalizers", "noads.handlers.render", nil, "nonut", "enabled" )
appendaction("math", "normalizers", "noads.handlers.collapse", nil, "nonut", "disabled" )
diff --git a/tex/context/base/mkxl/trac-vis.lmt b/tex/context/base/mkxl/trac-vis.lmt
index 255e26230..57583bf3c 100644
--- a/tex/context/base/mkxl/trac-vis.lmt
+++ b/tex/context/base/mkxl/trac-vis.lmt
@@ -1220,7 +1220,7 @@ end
local ruledstrut do
- local strut_size = 65536 / 2
+ local strut_size = 65536 * 8 / 10
local strut_code = nodes.rulecodes.strut
ruledstrut = function(head,current)
diff --git a/tex/context/fonts/mkiv/libertinus-math.lfg b/tex/context/fonts/mkiv/libertinus-math.lfg
index 1cf22f4d0..3930ce8e2 100644
--- a/tex/context/fonts/mkiv/libertinus-math.lfg
+++ b/tex/context/fonts/mkiv/libertinus-math.lfg
@@ -16,54 +16,54 @@ return {
NoLimitSubFactor = 1000,
FractionRuleThickness = 50,
OverbarRuleThickness = 50,
- -- RadicalRuleThickness = 50,
+ -- RadicalRuleThickness = 50,
UnderbarRuleThickness = 50,
- -- AccentBaseHeight = 0,
- -- AccentTopShiftUp = 0,
- AccentBaseDepth = 10,
+ -- AccentTopShiftUp = 0,
+ AccentBaseDepth = 10,
},
tweaks = {
aftercopying = {
{
tweak = "version",
- expected = "Version 6.8",
+ -- expected = "Version 6.8",
+ expected = "Version 7.040",
},
{
tweak = "dimensions",
list = {
- [0x00060] = { yoffset = -0.075 }, -- grave
- [0x000B4] = { yoffset = -0.075 }, -- acute
- [0x002C6] = { yoffset = -0.075 }, -- hat
- [0x002DC] = { yoffset = -0.075 }, -- tilde
- -- [0x000AF] = { yoffset = -0.1 }, -- bar
- [0x002D8] = { yoffset = -0.075 }, -- breve
- [0x002D9] = { yoffset = -0.05 }, -- dot
- [0x000A8] = { yoffset = -0.02 }, -- ddot
- [0x020DB] = { yoffset = -0.02 }, -- dddot
- [0x002DA] = { yoffset = -0.1 }, -- ring
- -- [0x002C7] = { yoffset = -0.1 }, -- check
- [0x020D7] = { yoffset = -0.1 }, -- vec
- [0x00300] = { yoffset = -0.1 , all=true }, -- widegrave
- [0x00301] = { yoffset = -0.1 , all=true }, -- wideacute
- [0x00302] = { yoffset = -0.1 , all=true }, -- widehat
+ [0x00060] = { yoffset = -0.075 }, -- grave
+ [0x000B4] = { yoffset = -0.075 }, -- acute
+ [0x002C6] = { yoffset = -0.075 }, -- hat
+ [0x002DC] = { yoffset = -0.075 }, -- tilde
+ -- [0x000AF] = { yoffset = -0.1 }, -- bar
+ [0x002D8] = { yoffset = -0.075 }, -- breve
+ [0x002D9] = { yoffset = -0.05 }, -- dot
+ [0x000A8] = { yoffset = -0.02 }, -- ddot
+ [0x020DB] = { yoffset = -0.02 }, -- dddot
+ [0x002DA] = { yoffset = -0.1 }, -- ring
+ -- [0x002C7] = { yoffset = -0.1 }, -- check
+ [0x020D7] = { yoffset = -0.1 }, -- vec
+ [0x00300] = { yoffset = -0.1 , all=true }, -- widegrave
+ [0x00301] = { yoffset = -0.1 , all=true }, -- wideacute
+ [0x00302] = { yoffset = -0.1 , all=true }, -- widehat
[0x00303] = { yoffset = -0.09 , all=true }, -- widetilde
- -- [0x00304] = { yoffset = -0.12 , all=true }, -- widebar
+ -- [0x00304] = { yoffset = -0.12 , all=true }, -- widebar
[0x00306] = { yoffset = -0.05 , all=true }, -- widebreve
[0x00307] = { yoffset = -0.02 , all=true }, -- widedot
[0x00308] = { yoffset = -0.02 , all=true }, -- wideddot
- -- [0x020DB] = { yoffset = -0.1 , all=true }, -- widedddot
+ -- [0x020DB] = { yoffset = -0.1 , all=true }, -- widedddot
[0x0030A] = { yoffset = -0.12 , all=true }, -- widering
[0x0030C] = { yoffset = -0.04 , all=true }, -- widecheck
- [0x1D44F] = { 0, 1, 0, 1.5 }, -- b
- [0x1D451] = { 0, 1, 0, 1.2 }, -- d
- [0x0210E] = { 0, 1, 0, 1.5 }, -- h
- [0x1D458] = { 0, 1, 0, 1.5 }, -- k
+ -- [0x1D44F] = { 0, 1, 0, 1.5 }, -- b (6.8)
+ -- [0x1D451] = { 0, 1, 0, 1.2 }, -- d (6.8)
+ -- [0x0210E] = { 0, 1, 0, 1.5 }, -- h (6.8)
+ -- [0x1D458] = { 0, 1, 0, 1.5 }, -- k (6.8)
},
},
{
tweak = "fixprimes",
scale = 0.9,
- -- smaller = true,
+ -- smaller = true,
factor = 0.9,
},
{
diff --git a/tex/context/fonts/mkiv/lucida-opentype-math.lfg b/tex/context/fonts/mkiv/lucida-opentype-math.lfg
index 769965386..6dc6eef2a 100644
--- a/tex/context/fonts/mkiv/lucida-opentype-math.lfg
+++ b/tex/context/fonts/mkiv/lucida-opentype-math.lfg
@@ -37,7 +37,7 @@ return {
NoLimitSupFactor = 0,
NoLimitSubFactor = 900,
FractionRuleThickness = 55,
- AccentBaseHeight = 650,
+ -- AccentBaseHeight = 650,
AccentBaseDepth = 150,
},
tweaks = {
@@ -47,6 +47,29 @@ return {
expected = "Version 1.802",
},
{
+ tweak = "substitutes",
+ list = {
+ [0x2264] = "ss03",
+ [0x2265] = "ss03",
+ }
+ },
+ -- \definefontfeature[mathlucida][copymathscripts=yes]
+ -- \definefontfeature[mathlucida][copymathscripts=yes,ss04=yes]
+ -- 0xFEOO should be chancery style, if present
+ {
+ tweak = "variants",
+ kind = "script",
+ feature = "ss04",-- this changes to chancery style for lucida
+ -- feature = false, -- use the saved ones (see typescript)
+ selector = 0xFE00,
+ },
+ -- 0xFEO1 should be roundhand style, if present
+ {
+ tweak = "variants",
+ kind = "script",
+ selector = 0xFE01,
+ },
+ {
tweak = "dimensions",
list = {
-- these we fix here
@@ -61,14 +84,14 @@ return {
-- [0x23DD] = { depth = .6, yoffset = 0.4 },
},
},
- {
- tweak = "fixprimes",
- factor = 0.9, -- accent base height
- -- smaller = true, -- replace multiples
- scale = 1, -- glyph scale
- -- fake = 0.65, -- replace multiples with this width proportion
- -- keep = true, -- keep the text size prime (aka minute)
- },
+ {
+ tweak = "fixprimes",
+ factor = 0.8, -- accent base height
+ -- smaller = true, -- replace multiples
+ scale = 1.1, -- glyph scale
+ -- fake = 0.65, -- replace multiples with this width proportion
+ -- keep = true, -- keep the text size prime (aka minute)
+ },
{
tweak = "checkspacing",
},
@@ -84,12 +107,11 @@ return {
},
},
alternates = {
- italic = { feature = 'ss01', value = 1, comment = "Mathematical Alternative Lowercase Italic" },
+ textitalic = { feature = 'ss01', value = 1, comment = "Mathematical Alternative Lowercase Italic" },
arrow = { feature = 'ss02', value = 1, comment = "Mathematical Alternative Smaller Arrows" },
operator = { feature = 'ss03', value = 1, comment = "Mathematical Alternative Smaller Operators" },
calligraphic = { feature = 'ss04', value = 1, comment = "Mathematical Alternative Calligraphic Characters" },
zero = { feature = 'ss05', value = 1, comment = "Mathematical Alternative Zero" },
- partial = { feature = 'ss20', value = 1, comment = "Mathematical Alternative Upright Partial Differential" },
},
bigslots = {
1, 2, 3, 4
diff --git a/tex/context/fonts/mkiv/stix-two-math.lfg b/tex/context/fonts/mkiv/stix-two-math.lfg
index d698167aa..6943e86ad 100644
--- a/tex/context/fonts/mkiv/stix-two-math.lfg
+++ b/tex/context/fonts/mkiv/stix-two-math.lfg
@@ -32,6 +32,20 @@ return {
tweak = "version",
expected = "Version 2.12 b168",
},
+ -- 0xFEOO should be chancery style, if present
+ {
+ tweak = "variants",
+ kind = "script",
+ -- feature = false, -- use the saved ones (see typescript)
+ selector = 0xFE00,
+ },
+ -- 0xFEO1 should be roundhand style, if present
+ {
+ tweak = "variants",
+ kind = "script",
+ feature = "ss01",-- this changes to roundhand style for stixtwo
+ selector = 0xFE01,
+ },
{
tweak = "dimensions",
list = {
diff --git a/tex/context/fonts/mkiv/type-imp-lucida-opentype.mkiv b/tex/context/fonts/mkiv/type-imp-lucida-opentype.mkiv
index 61002ff06..4ac23d4c1 100644
--- a/tex/context/fonts/mkiv/type-imp-lucida-opentype.mkiv
+++ b/tex/context/fonts/mkiv/type-imp-lucida-opentype.mkiv
@@ -13,6 +13,12 @@
% NOTA BENE: class features and goodies get expanded!
+\definefontfeature[mathlucida][copymathscripts=yes] % see lfg file
+
+% \definefontfeature[mathlucida][mathlucida][ss04=yes] % now we swap
+
+% \definefontfeature[mathlucida][ss03=yes]
+
\starttypescriptcollection[lucida-opentype]
\starttypescript [lucidaot,lucidadk]
@@ -23,8 +29,7 @@
\definetypeface [\typescriptone] [\s!hw] [\s!handwriting] [\typescriptone] [\s!default] [\s!features=\s!default]
\definetypeface [\typescriptone] [\s!cg] [\s!calligraphy] [\typescriptone] [\s!default] [\s!features=\s!default]
\definetypeface [\typescriptone] [\s!mm] [\s!math] [\typescriptone] [\s!default]
- % for the moment here:
- \setupmathrendering[\typescriptone][\s!it=\s!italic]
+ % no longer: \setupmathrendering[\typescriptone][\s!it=\s!italic]
\quittypescriptscanning
\stoptypescript
@@ -65,8 +70,8 @@
\stoptypescript
\starttypescript [\s!math] [lucidaot,lucidadk]
- \definefontsynonym [\s!MathRoman] [\s!file:LucidaBrightMathOT.otf] [\s!features={\s!math\mathsizesuffix,mathextra},\s!goodies=lucida-opentype-math]
- \definefontsynonym [\s!MathRomanBold] [\s!file:LucidaBrightMathOT-Demi.otf] [\s!features={\s!math\mathsizesuffix,mathextra},\s!goodies=lucida-opentype-math]
+ \definefontsynonym [\s!MathRoman] [\s!file:LucidaBrightMathOT.otf] [\s!features={\s!math\mathsizesuffix,mathlucida,mathextra},\s!goodies=lucida-opentype-math]
+ \definefontsynonym [\s!MathRomanBold] [\s!file:LucidaBrightMathOT-Demi.otf] [\s!features={\s!math\mathsizesuffix,mathlucida,mathextra},\s!goodies=lucida-opentype-math]
\stoptypescript
\starttypescript [\s!handwriting] [lucidaot,lucidadk]
diff --git a/tex/context/fonts/mkiv/type-imp-stix.mkiv b/tex/context/fonts/mkiv/type-imp-stix.mkiv
index ee11d8389..3104603e1 100644
--- a/tex/context/fonts/mkiv/type-imp-stix.mkiv
+++ b/tex/context/fonts/mkiv/type-imp-stix.mkiv
@@ -31,6 +31,9 @@
[stixtwomath]
[ss02=yes] % otherwise weird (non italic) g
+\definefontfeature[stixtwomath][copymathscripts=yes] % see lfg file
+
+
\starttypescriptcollection[stix]
% version one
diff --git a/tex/context/fonts/mkiv/type-imp-xits.mkiv b/tex/context/fonts/mkiv/type-imp-xits.mkiv
index d3504bdbb..f2d3e83c3 100644
--- a/tex/context/fonts/mkiv/type-imp-xits.mkiv
+++ b/tex/context/fonts/mkiv/type-imp-xits.mkiv
@@ -17,18 +17,20 @@
% scheduled for release by the end of 2010. Version 1.2, which will include Type 1
% fonts for use with LaTeX, will follow in 2011. So, we are on our own anyway.
+\definefontfeature[xitsmath][copymathscripts=yes] % see lfg file
+
\loadtypescriptfile[texgyre]
\starttypescriptcollection[xits]
\starttypescript [\s!math] [xits,xitsbidi] [\s!name]
\loadfontgoodies[xits-math]
- \definefontsynonym[\s!MathRoman ][\s!file:xitsmath-regular.otf] [\s!features={\s!math\mathsizesuffix,mathextra},\s!goodies=xits-math]
- \definefontsynonym[\s!MathRoman L2R][\s!file:xitsmath-regular.otf] [\s!features={\s!math\mathsizesuffix-l2r,mathextra},\s!goodies=xits-math]
- \definefontsynonym[\s!MathRoman R2L][\s!file:xitsmath-regular.otf] [\s!features={\s!math\mathsizesuffix-r2l,mathextra},\s!goodies=xits-math]
- \definefontsynonym[\s!MathRomanBold ][\s!file:xitsmath-bold.otf] [\s!features={\s!math\mathsizesuffix,mathextra},\s!goodies=xits-math]
- \definefontsynonym[\s!MathRomanBold L2R][\s!file:xitsmath-bold.otf] [\s!features={\s!math\mathsizesuffix-l2r,mathextra},\s!goodies=xits-math]
- \definefontsynonym[\s!MathRomanBold R2L][\s!file:xitsmath-bold.otf] [\s!features={\s!math\mathsizesuffix-r2l,mathextra},\s!goodies=xits-math]
+ \definefontsynonym[\s!MathRoman ][\s!file:xitsmath-regular.otf] [\s!features={\s!math\mathsizesuffix,mathextra,xitsmath},\s!goodies=xits-math]
+ \definefontsynonym[\s!MathRoman L2R][\s!file:xitsmath-regular.otf] [\s!features={\s!math\mathsizesuffix-l2r,mathextra,xitsmath},\s!goodies=xits-math]
+ \definefontsynonym[\s!MathRoman R2L][\s!file:xitsmath-regular.otf] [\s!features={\s!math\mathsizesuffix-r2l,mathextra,xitsmath},\s!goodies=xits-math]
+ \definefontsynonym[\s!MathRomanBold ][\s!file:xitsmath-bold.otf] [\s!features={\s!math\mathsizesuffix,mathextra,xitsmath},\s!goodies=xits-math]
+ \definefontsynonym[\s!MathRomanBold L2R][\s!file:xitsmath-bold.otf] [\s!features={\s!math\mathsizesuffix-l2r,mathextra,xitsmath},\s!goodies=xits-math]
+ \definefontsynonym[\s!MathRomanBold R2L][\s!file:xitsmath-bold.otf] [\s!features={\s!math\mathsizesuffix-r2l,mathextra,xitsmath},\s!goodies=xits-math]
\stoptypescript
\starttypescript [\s!serif] [xits] [\s!name]
diff --git a/tex/context/fonts/mkiv/xits-math.lfg b/tex/context/fonts/mkiv/xits-math.lfg
index 42a7052b9..6c4ac8b66 100644
--- a/tex/context/fonts/mkiv/xits-math.lfg
+++ b/tex/context/fonts/mkiv/xits-math.lfg
@@ -21,6 +21,20 @@ return {
tweak = "version",
expected = "Version 1.302",
},
+ -- 0xFEOO should be chancery style, if present
+ {
+ tweak = "variants",
+ kind = "script",
+ feature = "ss01",-- this changes to chancery style for xits
+ -- feature = false, -- use the saved ones (see typescript)
+ selector = 0xFE00,
+ },
+ -- 0xFEO1 should be roundhand style, if present
+ {
+ tweak = "variants",
+ kind = "script",
+ selector = 0xFE01,
+ },
{
tweak = "dimensions",
list = {
diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua
index c9dbfe3d6..ab4f8a66d 100644
--- a/tex/generic/context/luatex/luatex-fonts-merged.lua
+++ b/tex/generic/context/luatex/luatex-fonts-merged.lua
@@ -1,6 +1,6 @@
-- merged file : c:/data/develop/context/sources/luatex-fonts-merged.lua
-- parent file : c:/data/develop/context/sources/luatex-fonts.lua
--- merge date : 2022-03-12 11:24
+-- merge date : 2022-03-24 21:14
do -- begin closure to overcome local limits and interference
@@ -10903,9 +10903,9 @@ function mappings.addtounicode(data,filename,checklookups,forceligatures)
local usedmap=cidinfo and fonts.cid.getmap(cidinfo)
local uparser=makenameparser()
if usedmap then
- oparser=usedmap and makenameparser(cidinfo.ordering)
- cidnames=usedmap.names
- cidcodes=usedmap.unicodes
+ oparser=usedmap and makenameparser(cidinfo.ordering)
+ cidnames=usedmap.names
+ cidcodes=usedmap.unicodes
end
local ns=0
local nl=0
@@ -13109,13 +13109,13 @@ function readers.getinfo(filename,specification)
}
end
end
-function readers.rehash(fontdata,hashmethod)
+function readers.rehash()
report("the %a helper is not yet implemented","rehash")
end
-function readers.checkhash(fontdata)
+function readers.checkhash()
report("the %a helper is not yet implemented","checkhash")
end
-function readers.pack(fontdata,hashmethod)
+function readers.pack()
report("the %a helper is not yet implemented","pack")
end
function readers.unpack(fontdata)
@@ -15558,95 +15558,123 @@ local function applyaxis(glyph,shape,deltas,dowidth)
end
end
elseif cnt>0 then
- local function find(i)
- local prv=cnt
- for j=1,cnt do
- local nxt=dpoints[j]
- if nxt==i then
- return false,j,false
- elseif nxt>i then
- return prv,false,j
- end
- prv=j
- end
- return prv,false,1
- end
- for i=1,nofpoints do
- local d1,d2,d3=find(i)
- local p2=points[i]
- if d2 then
- xv[i]=xvalues[d2]
- yv[i]=yvalues[d2]
- else
- local n1=dpoints[d1]
- local n3=dpoints[d3]
- if n1>nofpoints then
- n1=nofpoints
- end
- if n3>nofpoints then
- n3=nofpoints
- end
- local p1=points[n1]
- local p3=points[n3]
- local p1x=p1[1]
- local p2x=p2[1]
- local p3x=p3[1]
- local p1y=p1[2]
- local p2y=p2[2]
- local p3y=p3[2]
- local x1=xvalues[d1]
- local y1=yvalues[d1]
- local x3=xvalues[d3]
- local y3=yvalues[d3]
- local fx
- local fy
- if p1x==p3x then
- if x1==x3 then
- fx=x1
- else
- fx=0
- end
- elseif p2x<=min(p1x,p3x) then
- if p1x<p3x then
- fx=x1
- else
- fx=x3
- end
- elseif p2x>=max(p1x,p3x) then
- if p1x>p3x then
- fx=x1
- else
- fx=x3
+ local contours=shape.contours
+ local nofcontours=#contours
+ local first=1
+ local firstindex=1
+ for contour=1,nofcontours do
+ local last=contours[contour]
+ if last>=first then
+ local lastindex=cnt
+ if firstindex<cnt then
+ for currentindex=firstindex,cnt do
+ local found=dpoints[currentindex]
+ if found<=first then
+ firstindex=currentindex
+ end
+ if found==last then
+ lastindex=currentindex
+ break;
+ elseif found>last then
+ break
+ end
end
- else
- fx=(p2x-p1x)/(p3x-p1x)
- fx=(1-fx)*x1+fx*x3
end
- if p1y==p3y then
- if y1==y3 then
- fy=y1
- else
- fy=0
- end
- elseif p2y<=min(p1y,p3y) then
- if p1y<p3y then
- fy=y1
- else
- fy=y3
+ local function find(i)
+ local prv=lastindex
+ for j=firstindex,lastindex do
+ local nxt=dpoints[j]
+ if nxt==i then
+ return false,j,false
+ elseif nxt>i then
+ return prv,false,j
+ end
+ prv=j
end
- elseif p2y>=max(p1y,p3y) then
- if p1y>p3y then
- fy=y1
+ return prv,false,firstindex
+ end
+ for point=first,last do
+ local d1,d2,d3=find(point)
+ local p2=points[point]
+ if d2 then
+ xv[point]=xvalues[d2]
+ yv[point]=yvalues[d2]
else
- fy=y3
+ local n1=dpoints[d1]
+ local n3=dpoints[d3]
+ if n1>nofpoints then
+ n1=nofpoints
+ end
+ if n3>nofpoints then
+ n3=nofpoints
+ end
+ local p1=points[n1]
+ local p3=points[n3]
+ local p1x=p1[1]
+ local p2x=p2[1]
+ local p3x=p3[1]
+ local p1y=p1[2]
+ local p2y=p2[2]
+ local p3y=p3[2]
+ local x1=xvalues[d1]
+ local y1=yvalues[d1]
+ local x3=xvalues[d3]
+ local y3=yvalues[d3]
+ local fx
+ local fy
+ if p1x==p3x then
+ if x1==x3 then
+ fx=x1
+ else
+ fx=0
+ end
+ elseif p2x<=min(p1x,p3x) then
+ if p1x<p3x then
+ fx=x1
+ else
+ fx=x3
+ end
+ elseif p2x>=max(p1x,p3x) then
+ if p1x>p3x then
+ fx=x1
+ else
+ fx=x3
+ end
+ else
+ fx=(p2x-p1x)/(p3x-p1x)
+ fx=(1-fx)*x1+fx*x3
+ end
+ if p1y==p3y then
+ if y1==y3 then
+ fy=y1
+ else
+ fy=0
+ end
+ elseif p2y<=min(p1y,p3y) then
+ if p1y<p3y then
+ fy=y1
+ else
+ fy=y3
+ end
+ elseif p2y>=max(p1y,p3y) then
+ if p1y>p3y then
+ fy=y1
+ else
+ fy=y3
+ end
+ else
+ fy=(p2y-p1y)/(p3y-p1y)
+ fy=(1-fy)*y1+fy*y3
+ end
+ xv[point]=fx
+ yv[point]=fy
end
- else
- fy=(p2y-p1y)/(p3y-p1y)
- fy=(1-fy)*y1+fy*y3
end
- xv[i]=fx
- yv[i]=fy
+ if lastindex<cnt then
+ firstindex=lastindex+1
+ end
end
+ first=last+1
end
for i=1,nofpoints do
local pi=points[i]
@@ -19793,6 +19821,7 @@ function readers.hvar(f,fontdata,specification)
local variations={}
local innerindex={}
local outerindex={}
+ local deltas={}
if variationoffset>0 then
regions,deltas=readvariationdata(f,variationoffset,factors)
end
@@ -21182,7 +21211,7 @@ local trace_defining=false registertracker("fonts.defining",function(v) trace_d
local report_otf=logs.reporter("fonts","otf loading")
local fonts=fonts
local otf=fonts.handlers.otf
-otf.version=3.119
+otf.version=3.120
otf.cache=containers.define("fonts","otl",otf.version,true)
otf.svgcache=containers.define("fonts","svg",otf.version,true)
otf.pngcache=containers.define("fonts","png",otf.version,true)
@@ -23856,6 +23885,7 @@ local next,type=next,type
local P,R,S=lpeg.P,lpeg.R,lpeg.S
local lpegmatch=lpeg.match
local insert,remove,copy,unpack=table.insert,table.remove,table.copy,table.unpack
+local find=string.find
local formatters=string.formatters
local sortedkeys=table.sortedkeys
local sortedhash=table.sortedhash
@@ -24714,61 +24744,137 @@ local function unifyglyphs(fontdata,usenames)
fontdata.nofglyphs=nofglyphs
return indices,names
end
-local p_crappyname do
+local stripredundant do
local p_hex=R("af","AF","09")
local p_digit=R("09")
local p_done=S("._-")^0+P(-1)
+ local p_style=P(".")
local p_alpha=R("az","AZ")
local p_ALPHA=R("AZ")
- p_crappyname=(
+ local p_crappyname=(
lpeg.utfchartabletopattern({ "uni","u" },true)*S("Xx_")^0*p_hex^1
+lpeg.utfchartabletopattern({ "identity","glyph","jamo" },true)*p_hex^1
+lpeg.utfchartabletopattern({ "index","afii" },true)*p_digit^1
+p_digit*p_hex^3+p_alpha*p_digit^1
+P("aj")*p_digit^1+P("eh_")*(p_digit^1+p_ALPHA*p_digit^1)+(1-P("_"))^1*P("_uni")*p_hex^1+P("_")*P(1)^1
)*p_done
-end
-local forcekeep=false
-directives.register("otf.keepnames",function(v)
- report_cleanup("keeping weird glyph names, expect larger files and more memory usage")
- forcekeep=v
-end)
-local function stripredundant(fontdata)
- local descriptions=fontdata.descriptions
- if descriptions then
- local n=0
- local c=0
- if (not context and fonts.privateoffsets.keepnames) or forcekeep then
- for unicode,d in next,descriptions do
- if d.class=="base" then
- d.class=nil
- c=c+1
+ if context then
+ local forcekeep=false
+ directives.register("otf.keepnames",function(v)
+ report_cleanup("keeping weird glyph names, expect larger files and more memory usage")
+ forcekeep=v
+ end)
+ local function stripvariants(descriptions,list)
+ local n=list and #list or 0
+ if n>0 then
+ for i=1,n do
+ local g=list[i]
+ if g then
+ local d=descriptions[g]
+ if d and d.name then
+ d.name=nil
+ n=n+1
+ end
+ end
end
end
- else
- for unicode,d in next,descriptions do
- local name=d.name
- if name and lpegmatch(p_crappyname,name) then
- d.name=nil
- n=n+1
- end
- if d.class=="base" then
- d.class=nil
- c=c+1
+ return n
+ end
+ local function stripparts(descriptions,list)
+ local n=list and #list or 0
+ if n>0 then
+ for i=1,n do
+ local g=list[i].glyph
+ if g then
+ local d=descriptions[g]
+ if d and d.name then
+ d.name=nil
+ n=n+1
+ end
+ end
end
end
+ return n
end
- if trace_cleanup then
- if n>0 then
- report_cleanup("%s bogus names removed (verbose unicode)",n)
+ local function collectsimple(fontdata)
+ return nil
+ end
+ stripredundant=function(fontdata)
+ local descriptions=fontdata.descriptions
+ if descriptions then
+ local n=0
+ local c=0
+ for unicode,d in next,descriptions do
+ local m=d.math
+ if m then
+ n=n+stripvariants(descriptions,m.vvariants)
+ n=n+stripvariants(descriptions,m.hvariants)
+ n=n+stripparts (descriptions,m.vparts)
+ n=n+stripparts (descriptions,m.hparts)
+ end
+ end
+ if forcekeep then
+ for unicode,d in next,descriptions do
+ if d.class=="base" then
+ d.class=nil
+ c=c+1
+ end
+ end
+ else
+ local keeplist=collectsimple(fontdata)
+ for unicode,d in next,descriptions do
+ local name=d.name
+ if name then
+ if keeplist and keeplist[name] then
+ elseif lpegmatch(p_crappyname,name) then
+ d.name=nil
+ n=n+1
+ end
+ end
+ if d.class=="base" then
+ d.class=nil
+ c=c+1
+ end
+ end
+ end
+ if trace_cleanup then
+ if n>0 then
+ report_cleanup("%s bogus names removed (verbose unicode)",n)
+ end
+ if c>0 then
+ report_cleanup("%s base class tags removed (default is base)",c)
+ end
+ end
end
- if c>0 then
- report_cleanup("%s base class tags removed (default is base)",c)
+ end
+ else
+ stripredundant=function(fontdata)
+ local descriptions=fontdata.descriptions
+ if descriptions then
+ if fonts.privateoffsets.keepnames then
+ for unicode,d in next,descriptions do
+ if d.class=="base" then
+ d.class=nil
+ end
+ end
+ else
+ for unicode,d in next,descriptions do
+ local name=d.name
+ if name then
+ if lpegmatch(p_crappyname,name) then
+ d.name=nil
+ end
+ end
+ if d.class=="base" then
+ d.class=nil
+ end
+ end
+ end
end
end
end
+ readers.stripredundant=stripredundant
end
-readers.stripredundant=stripredundant
function readers.getcomponents(fontdata)
local resources=fontdata.resources
if resources then
@@ -24852,8 +24958,7 @@ readers.unifymissing=unifymissing
function readers.rehash(fontdata,hashmethod)
if not (fontdata and fontdata.glyphs) then
return
- end
- if hashmethod=="indices" then
+ elseif hashmethod=="indices" then
fontdata.hashmethod="indices"
elseif hashmethod=="names" then
fontdata.hashmethod="names"