summaryrefslogtreecommitdiff
path: root/tex
diff options
context:
space:
mode:
authorHans Hagen <pragma@wxs.nl>2013-06-10 12:24:00 +0200
committerHans Hagen <pragma@wxs.nl>2013-06-10 12:24:00 +0200
commitb4a7a2353b029fcff03f5e3668d98ef61f03df3f (patch)
tree79b26772ecd40c741b7c8104c355cc019bb4e3c0 /tex
parent06598aba33407bf903137696d65f2d7988e2748a (diff)
downloadcontext-b4a7a2353b029fcff03f5e3668d98ef61f03df3f.tar.gz
beta 2013.06.10 12:24
Diffstat (limited to 'tex')
-rw-r--r--tex/context/base/char-def.lua11
-rw-r--r--tex/context/base/cont-new.mkii2
-rw-r--r--tex/context/base/cont-new.mkiv2
-rw-r--r--tex/context/base/context-version.pdfbin4134 -> 4131 bytes
-rw-r--r--tex/context/base/context.mkii2
-rw-r--r--tex/context/base/context.mkiv2
-rw-r--r--tex/context/base/font-chk.lua51
-rw-r--r--tex/context/base/font-ctx.lua30
-rw-r--r--tex/context/base/font-otd.lua26
-rw-r--r--tex/context/base/font-otn.lua2
-rw-r--r--tex/context/base/l-table.lua380
-rw-r--r--tex/context/base/lpdf-ano.lua32
-rw-r--r--tex/context/base/math-act.lua76
-rw-r--r--tex/context/base/math-ini.lua27
-rw-r--r--tex/context/base/math-ini.mkiv6
-rw-r--r--tex/context/base/math-stc.mkvi18
-rw-r--r--tex/context/base/node-fin.lua716
-rw-r--r--tex/context/base/node-pro.lua3
-rw-r--r--tex/context/base/node-rul.mkiv44
-rw-r--r--tex/context/base/spac-ver.mkiv6
-rw-r--r--tex/context/base/status-files.pdfbin24681 -> 24645 bytes
-rw-r--r--tex/context/base/status-lua.pdfbin212042 -> 213142 bytes
-rw-r--r--tex/context/base/strc-ref.lua2
-rw-r--r--tex/context/base/trac-vis.lua24
-rw-r--r--tex/context/base/util-str.lua14
-rw-r--r--tex/context/base/util-tab.lua416
-rw-r--r--tex/context/base/util-tpl.lua22
-rw-r--r--tex/context/base/x-mathml.mkiv100
-rw-r--r--tex/context/fonts/lm.lfg5
-rw-r--r--tex/generic/context/luatex/luatex-fonts-merged.lua69
30 files changed, 761 insertions, 1327 deletions
diff --git a/tex/context/base/char-def.lua b/tex/context/base/char-def.lua
index 7d2df5d41..f64efa5c3 100644
--- a/tex/context/base/char-def.lua
+++ b/tex/context/base/char-def.lua
@@ -57678,16 +57678,19 @@ characters.data={
description="OVERLINE",
direction="on",
linebreak="al",
+ mathextensible="l",
+ comment=[[mathspec={ { class="topaccent", name="overbar" }, { class="botaccent", name="underbar" } }"]],
mathspec={
{
- class="topaccent",
- name="overbar",
+ class="under",
+ name="underbar",
},
{
- class="botaccent",
- name="underbar",
+ class="over",
+ name="overbar",
},
},
+ mathstretch="h",
specials={ "compat", 0x0020, 0x0305 },
unicodeslot=0x203E,
},
diff --git a/tex/context/base/cont-new.mkii b/tex/context/base/cont-new.mkii
index 544e5e537..f0385c065 100644
--- a/tex/context/base/cont-new.mkii
+++ b/tex/context/base/cont-new.mkii
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\newcontextversion{2013.04.09 10:38}
+\newcontextversion{2013.06.07 17:34}
%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/cont-new.mkiv b/tex/context/base/cont-new.mkiv
index 60a4e45f8..7b585b38a 100644
--- a/tex/context/base/cont-new.mkiv
+++ b/tex/context/base/cont-new.mkiv
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\newcontextversion{2013.06.07 12:25}
+\newcontextversion{2013.06.10 12:24}
%D This file is loaded at runtime, thereby providing an excellent place for
%D hacks, patches, extensions and new features.
diff --git a/tex/context/base/context-version.pdf b/tex/context/base/context-version.pdf
index c5561b93e..8aed0b0df 100644
--- a/tex/context/base/context-version.pdf
+++ b/tex/context/base/context-version.pdf
Binary files differ
diff --git a/tex/context/base/context.mkii b/tex/context/base/context.mkii
index 97afd33df..990c8bd11 100644
--- a/tex/context/base/context.mkii
+++ b/tex/context/base/context.mkii
@@ -20,7 +20,7 @@
%D your styles an modules.
\edef\contextformat {\jobname}
-\edef\contextversion{2013.04.09 10:38}
+\edef\contextversion{2013.06.07 17:34}
%D For those who want to use this:
diff --git a/tex/context/base/context.mkiv b/tex/context/base/context.mkiv
index 3eb8c9a76..0e48ae1c4 100644
--- a/tex/context/base/context.mkiv
+++ b/tex/context/base/context.mkiv
@@ -25,7 +25,7 @@
%D up and the dependencies are more consistent.
\edef\contextformat {\jobname}
-\edef\contextversion{2013.06.07 12:25}
+\edef\contextversion{2013.06.10 12:24}
\edef\contextkind {beta}
%D For those who want to use this:
diff --git a/tex/context/base/font-chk.lua b/tex/context/base/font-chk.lua
index 1b89366fd..467afae9b 100644
--- a/tex/context/base/font-chk.lua
+++ b/tex/context/base/font-chk.lua
@@ -9,8 +9,9 @@ if not modules then modules = { } end modules ['font-chk'] = {
-- possible optimization: delayed initialization of vectors
-- move to the nodes namespace
-local format = string.format
+local formatters = string.formatters
local bpfactor = number.dimenfactors.bp
+local fastcopy = table.fastcopy
local report_fonts = logs.reporter("fonts","checking")
@@ -23,9 +24,11 @@ local fonthashes = fonts.hashes
local fontdata = fonthashes.identifiers
local fontcharacters = fonthashes.characters
-local addprivate = fonts.helpers.addprivate
-local hasprivate = fonts.helpers.hasprivate
-local getprivatenode = fonts.helpers.getprivatenode
+local helpers = fonts.helpers
+
+local addprivate = helpers.addprivate
+local hasprivate = helpers.hasprivate
+local getprivatenode = helpers.getprivatenode
local otffeatures = fonts.constructors.newfeatures("otf")
local registerotffeature = otffeatures.register
@@ -147,7 +150,7 @@ local variants = {
{ tag = "yellow", r = .6, g = .6, b = 0 },
}
-local package = "q %0.6f 0 0 %0.6f 0 0 cm %s %s %s rg %s %s %s RG 10 M 1 j 1 J 0.05 w %s Q"
+local pdf_blob = "pdf: q %0.6f 0 0 %0.6f 0 0 cm %s %s %s rg %s %s %s RG 10 M 1 j 1 J 0.05 w %s Q"
local cache = { } -- saves some tables but not that impressive
@@ -162,9 +165,9 @@ local function addmissingsymbols(tfmdata) -- we can have an alternative with rul
for i =1, #fakes do
local fake = fakes[i]
local name = fake.name
- local privatename = format("placeholder %s %s",name,tag)
+ local privatename = formatters["placeholder %s %s"](name,tag)
if not hasprivate(tfmdata,privatename) then
- local hash = format("%s_%s_%s_%s_%s_%s",name,tag,r,g,b,size)
+ local hash = formatters["%s_%s_%s_%s_%s_%s"](name,tag,r,g,b,size)
local char = cache[hash]
if not char then
char = {
@@ -172,7 +175,7 @@ local function addmissingsymbols(tfmdata) -- we can have an alternative with rul
height = size*fake.height,
depth = size*fake.depth,
-- bah .. low level pdf ... should be a rule or plugged in
- commands = { { "special", "pdf: " .. format(package,scale,scale,r,g,b,r,g,b,fake.code) } }
+ commands = { { "special", formatters[pdf_blob](scale,scale,r,g,b,r,g,b,fake.code) } }
}
cache[hash] = char
end
@@ -197,7 +200,7 @@ fonts.loggers.category_to_placeholder = mapping
function commands.getplaceholderchar(name)
local id = font.current()
addmissingsymbols(fontdata[id])
- context(fonts.helpers.getprivatenode(fontdata[id],name))
+ context(helpers.getprivatenode(fontdata[id],name))
end
function checkers.missing(head)
@@ -357,3 +360,33 @@ luatex.registerstopactions(function()
end
end
end)
+
+-- for the moment here
+
+function helpers.expandglyph(characters,index,done)
+ done = done or { }
+ if not done[index] then
+ local data = characters[index]
+ if data then
+ done[index] = true
+ local d = fastcopy(data)
+ local n = d.next
+ if n then
+ d.next = expandglyph(characters,n,done)
+ end
+ local h = d.horiz_variants
+ if h then
+ for i=1,#h do
+ h[i].glyph = expandglyph(characters,h[i].glyph,done)
+ end
+ end
+ local v = d.vert_variants
+ if v then
+ for i=1,#v do
+ v[i].glyph = expandglyph(characters,v[i].glyph,done)
+ end
+ end
+ return d
+ end
+ end
+end
diff --git a/tex/context/base/font-ctx.lua b/tex/context/base/font-ctx.lua
index 63d10d007..31de74578 100644
--- a/tex/context/base/font-ctx.lua
+++ b/tex/context/base/font-ctx.lua
@@ -617,19 +617,39 @@ specifiers.definecontext = definecontext
-- we extend the hasher:
+-- constructors.hashmethods.virtual = function(list)
+-- local s = { }
+-- local n = 0
+-- for k, v in next, list do
+-- n = n + 1
+-- s[n] = k -- no checking on k
+-- end
+-- if n > 0 then
+-- sort(s)
+-- for i=1,n do
+-- local k = s[i]
+-- s[i] = k .. '=' .. tostring(list[k])
+-- end
+-- return concat(s,"+")
+-- end
+-- end
+
constructors.hashmethods.virtual = function(list)
local s = { }
local n = 0
for k, v in next, list do
n = n + 1
- s[n] = k -- no checking on k
+ -- if v == true then
+ -- s[n] = k .. '=true'
+ -- elseif v == false then
+ -- s[n] = k .. '=false'
+ -- else
+ -- s[n] = k .. "=" .. v
+ -- end
+ s[n] = k .. "=" .. tostring(v)
end
if n > 0 then
sort(s)
- for i=1,n do
- local k = s[i]
- s[i] = k .. '=' .. tostring(list[k])
- end
return concat(s,"+")
end
end
diff --git a/tex/context/base/font-otd.lua b/tex/context/base/font-otd.lua
index a9d093d6d..919da2379 100644
--- a/tex/context/base/font-otd.lua
+++ b/tex/context/base/font-otd.lua
@@ -242,19 +242,19 @@ function otf.dataset(tfmdata,font,attr) -- attr only when explicit (as in specia
}
rl[attr] = ra
local sequences = tfmdata.resources.sequences
--- setmetatableindex(ra, function(t,k)
--- if type(k) == "number" then
--- local v = initialize(sequences[k],script,language,s_enabled,a_enabled,font,attr,dynamic)
--- t[k] = v or false
--- return v
--- end
--- end)
-for s=1,#sequences do
- local v = initialize(sequences[s],script,language,s_enabled,a_enabled,font,attr,dynamic)
- if v then
- ra[#ra+1] = v
- end
-end
+ -- setmetatableindex(ra, function(t,k)
+ -- if type(k) == "number" then
+ -- local v = initialize(sequences[k],script,language,s_enabled,a_enabled,font,attr,dynamic)
+ -- t[k] = v or false
+ -- return v
+ -- end
+ -- end)
+ for s=1,#sequences do
+ local v = initialize(sequences[s],script,language,s_enabled,a_enabled,font,attr,dynamic)
+ if v then
+ ra[#ra+1] = v
+ end
+ end
end
return ra
diff --git a/tex/context/base/font-otn.lua b/tex/context/base/font-otn.lua
index f462c0db4..e0cb9acbc 100644
--- a/tex/context/base/font-otn.lua
+++ b/tex/context/base/font-otn.lua
@@ -2209,8 +2209,6 @@ local function featuresprocessor(head,font,attr)
else
start = start.next
end
- elseif id == math_code then
- start = end_of_math(start).next
else
start = start.next
end
diff --git a/tex/context/base/l-table.lua b/tex/context/base/l-table.lua
index 493a82084..4f6b9b4ed 100644
--- a/tex/context/base/l-table.lua
+++ b/tex/context/base/l-table.lua
@@ -366,12 +366,12 @@ local function simple_table(t)
else
tt[nt] = tostring(v) -- tostring not needed
end
- elseif tv == "boolean" then
- nt = nt + 1
- tt[nt] = tostring(v)
elseif tv == "string" then
nt = nt + 1
tt[nt] = format("%q",v)
+ elseif tv == "boolean" then
+ nt = nt + 1
+ tt[nt] = v and "true" or "false"
else
tt = nil
break
@@ -397,7 +397,8 @@ end
-- todo: %g faster on numbers than %s
--- we can speed this up with repeaters and formatters (is indeed faster)
+-- we can speed this up with repeaters and formatters but we haven't defined them
+-- yet
local propername = patterns.propername -- was find(name,"^%a[%w%_]*$")
@@ -423,7 +424,7 @@ local function do_serialize(root,name,depth,level,indexed)
handle(format("%s[%q]={",depth,name))
end
elseif tn == "boolean" then
- handle(format("%s[%s]={",depth,tostring(name)))
+ handle(format("%s[%s]={",depth,name and "true" or "false"))
else
handle(format("%s{",depth))
end
@@ -459,21 +460,21 @@ local function do_serialize(root,name,depth,level,indexed)
--~ if v == root then
-- circular
--~ else
- local t, tk = type(v), type(k)
+ local tv, tk = type(v), type(k)
if compact and first and tk == "number" and k >= first and k <= last then
- if t == "number" then
+ if tv == "number" then
if hexify then
handle(format("%s 0x%04X,",depth,v))
else
handle(format("%s %s,",depth,v)) -- %.99g
end
- elseif t == "string" then
+ elseif tv == "string" then
if reduce and tonumber(v) then
handle(format("%s %s,",depth,v))
else
handle(format("%s %q,",depth,v))
end
- elseif t == "table" then
+ elseif tv == "table" then
if not next(v) then
handle(format("%s {},",depth))
elseif inline then -- and #t > 0
@@ -486,9 +487,9 @@ local function do_serialize(root,name,depth,level,indexed)
else
do_serialize(v,k,depth,level+1,true)
end
- elseif t == "boolean" then
- handle(format("%s %s,",depth,tostring(v)))
- elseif t == "function" then
+ elseif tv == "boolean" then
+ handle(format("%s %s,",depth,v and "true" or "false"))
+ elseif tv == "function" then
if functions then
handle(format('%s load(%q),',depth,dump(v))) -- maybe strip
else
@@ -501,7 +502,7 @@ local function do_serialize(root,name,depth,level,indexed)
if false then
handle(format("%s __p__=nil,",depth))
end
- elseif t == "number" then
+ elseif tv == "number" then
if tk == "number" then
if hexify then
handle(format("%s [0x%04X]=0x%04X,",depth,k,v))
@@ -510,9 +511,9 @@ local function do_serialize(root,name,depth,level,indexed)
end
elseif tk == "boolean" then
if hexify then
- handle(format("%s [%s]=0x%04X,",depth,tostring(k),v))
+ handle(format("%s [%s]=0x%04X,",depth,k and "true" or "false",v))
else
- handle(format("%s [%s]=%s,",depth,tostring(k),v)) -- %.99g
+ handle(format("%s [%s]=%s,",depth,k and "true" or "false",v)) -- %.99g
end
elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
if hexify then
@@ -527,7 +528,7 @@ local function do_serialize(root,name,depth,level,indexed)
handle(format("%s [%q]=%s,",depth,k,v)) -- %.99g
end
end
- elseif t == "string" then
+ elseif tv == "string" then
if reduce and tonumber(v) then
if tk == "number" then
if hexify then
@@ -536,7 +537,7 @@ local function do_serialize(root,name,depth,level,indexed)
handle(format("%s [%s]=%s,",depth,k,v))
end
elseif tk == "boolean" then
- handle(format("%s [%s]=%s,",depth,tostring(k),v))
+ handle(format("%s [%s]=%s,",depth,k and "true" or "false",v))
elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
handle(format("%s %s=%s,",depth,k,v))
else
@@ -550,14 +551,14 @@ local function do_serialize(root,name,depth,level,indexed)
handle(format("%s [%s]=%q,",depth,k,v))
end
elseif tk == "boolean" then
- handle(format("%s [%s]=%q,",depth,tostring(k),v))
+ handle(format("%s [%s]=%q,",depth,k and "true" or "false",v))
elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
handle(format("%s %s=%q,",depth,k,v))
else
handle(format("%s [%q]=%q,",depth,k,v))
end
end
- elseif t == "table" then
+ elseif tv == "table" then
if not next(v) then
if tk == "number" then
if hexify then
@@ -566,7 +567,7 @@ local function do_serialize(root,name,depth,level,indexed)
handle(format("%s [%s]={},",depth,k))
end
elseif tk == "boolean" then
- handle(format("%s [%s]={},",depth,tostring(k)))
+ handle(format("%s [%s]={},",depth,k and "true" or "false"))
elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
handle(format("%s %s={},",depth,k))
else
@@ -582,7 +583,7 @@ local function do_serialize(root,name,depth,level,indexed)
handle(format("%s [%s]={ %s },",depth,k,concat(st,", ")))
end
elseif tk == "boolean" then
- handle(format("%s [%s]={ %s },",depth,tostring(k),concat(st,", ")))
+ handle(format("%s [%s]={ %s },",depth,k and "true" or "false",concat(st,", ")))
elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
handle(format("%s %s={ %s },",depth,k,concat(st,", ")))
else
@@ -594,21 +595,21 @@ local function do_serialize(root,name,depth,level,indexed)
else
do_serialize(v,k,depth,level+1)
end
- elseif t == "boolean" then
+ elseif tv == "boolean" then
if tk == "number" then
if hexify then
- handle(format("%s [0x%04X]=%s,",depth,k,tostring(v)))
+ handle(format("%s [0x%04X]=%s,",depth,k,v and "true" or "false"))
else
- handle(format("%s [%s]=%s,",depth,k,tostring(v)))
+ handle(format("%s [%s]=%s,",depth,k,v and "true" or "false"))
end
elseif tk == "boolean" then
- handle(format("%s [%s]=%s,",depth,tostring(k),tostring(v)))
+ handle(format("%s [%s]=%s,",depth,tostring(k),v and "true" or "false"))
elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
- handle(format("%s %s=%s,",depth,k,tostring(v)))
+ handle(format("%s %s=%s,",depth,k,v and "true" or "false"))
else
- handle(format("%s [%q]=%s,",depth,k,tostring(v)))
+ handle(format("%s [%q]=%s,",depth,k,v and "true" or "false"))
end
- elseif t == "function" then
+ elseif tv == "function" then
if functions then
local f = getinfo(v).what == "C" and dump(dummy) or dump(v) -- maybe strip
-- local f = getinfo(v).what == "C" and dump(function(...) return v(...) end) or dump(v) -- maybe strip
@@ -619,7 +620,7 @@ local function do_serialize(root,name,depth,level,indexed)
handle(format("%s [%s]=load(%q),",depth,k,f))
end
elseif tk == "boolean" then
- handle(format("%s [%s]=load(%q),",depth,tostring(k),f))
+ handle(format("%s [%s]=load(%q),",depth,k and "true" or "false",f))
elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
handle(format("%s %s=load(%q),",depth,k,f))
else
@@ -634,7 +635,7 @@ local function do_serialize(root,name,depth,level,indexed)
handle(format("%s [%s]=%q,",depth,k,tostring(v)))
end
elseif tk == "boolean" then
- handle(format("%s [%s]=%q,",depth,tostring(k),tostring(v)))
+ handle(format("%s [%s]=%q,",depth,k and "true" or "false",tostring(v)))
elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
handle(format("%s %s=%q,",depth,k,tostring(v)))
else
@@ -716,321 +717,10 @@ local function serialize(_handle,root,name,specification) -- handle wins
handle("}")
end
--- -- This is some 20% faster than using format (because formatters are much faster) but
--- -- of course, inlining the format using .. is then again faster .. anyway, as we do
--- -- some pretty printing as well there is not that much to gain unless we make a 'fast'
--- -- ugly variant as well. But, we would have to move the formatter to l-string then.
-
--- local formatters = string.formatters
-
--- local function do_serialize(root,name,level,indexed)
--- if level > 0 then
--- if indexed then
--- handle(formatters["%w{"](level))
--- else
--- local tn = type(name)
--- if tn == "number" then
--- if hexify then
--- handle(formatters["%w[%04H]={"](level,name))
--- else
--- handle(formatters["%w[%s]={"](level,name))
--- end
--- elseif tn == "string" then
--- if noquotes and not reserved[name] and lpegmatch(propername,name) then
--- handle(formatters["%w%s={"](level,name))
--- else
--- handle(formatters["%w[%q]={"](level,name))
--- end
--- elseif tn == "boolean" then
--- handle(formatters["%w[%S]={"](level,name))
--- else
--- handle(formatters["%w{"](level))
--- end
--- end
--- end
--- -- we could check for k (index) being number (cardinal)
--- if root and next(root) then
--- -- local first, last = nil, 0 -- #root cannot be trusted here (will be ok in 5.2 when ipairs is gone)
--- -- if compact then
--- -- -- NOT: for k=1,#root do (we need to quit at nil)
--- -- for k,v in ipairs(root) do -- can we use next?
--- -- if not first then first = k end
--- -- last = last + 1
--- -- end
--- -- end
--- local first, last = nil, 0
--- if compact then
--- last = #root
--- for k=1,last do
--- if root[k] == nil then
--- last = k - 1
--- break
--- end
--- end
--- if last > 0 then
--- first = 1
--- end
--- end
--- local sk = sortedkeys(root)
--- for i=1,#sk do
--- local k = sk[i]
--- local v = root[k]
--- --~ if v == root then
--- -- circular
--- --~ else
--- local t, tk = type(v), type(k)
--- if compact and first and tk == "number" and k >= first and k <= last then
--- if t == "number" then
--- if hexify then
--- handle(formatters["%w %04H,"](level,v))
--- else
--- handle(formatters["%w %s,"](level,v)) -- %.99g
--- end
--- elseif t == "string" then
--- if reduce and tonumber(v) then
--- handle(formatters["%w %s,"](level,v))
--- else
--- handle(formatters["%w %q,"](level,v))
--- end
--- elseif t == "table" then
--- if not next(v) then
--- handle(formatters["%w {},"](level))
--- elseif inline then -- and #t > 0
--- local st = simple_table(v)
--- if st then
--- handle(formatters["%w { %, t },"](level,st))
--- else
--- do_serialize(v,k,level+1,true)
--- end
--- else
--- do_serialize(v,k,level+1,true)
--- end
--- elseif t == "boolean" then
--- handle(formatters["%w %S,"](level,v))
--- elseif t == "function" then
--- if functions then
--- handle(formatters['%w load(%q),'](level,dump(v))) -- maybe strip
--- else
--- handle(formatters['%w "function",'](level))
--- end
--- else
--- handle(formatters["%w %Q,"](level,v))
--- end
--- elseif k == "__p__" then -- parent
--- if false then
--- handle(formatters["%w __p__=nil,"](level))
--- end
--- elseif t == "number" then
--- if tk == "number" then
--- if hexify then
--- handle(formatters["%w [%04H]=%04H,"](level,k,v))
--- else
--- handle(formatters["%w [%s]=%s,"](level,k,v)) -- %.99g
--- end
--- elseif tk == "boolean" then
--- if hexify then
--- handle(formatters["%w [%S]=%04H,"](level,k,v))
--- else
--- handle(formatters["%w [%S]=%s,"](level,k,v)) -- %.99g
--- end
--- elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
--- if hexify then
--- handle(formatters["%w %s=%04H,"](level,k,v))
--- else
--- handle(formatters["%w %s=%s,"](level,k,v)) -- %.99g
--- end
--- else
--- if hexify then
--- handle(formatters["%w [%q]=%04H,"](level,k,v))
--- else
--- handle(formatters["%w [%q]=%s,"](level,k,v)) -- %.99g
--- end
--- end
--- elseif t == "string" then
--- if reduce and tonumber(v) then
--- if tk == "number" then
--- if hexify then
--- handle(formatters["%w [%04H]=%s,"](level,k,v))
--- else
--- handle(formatters["%w [%s]=%s,"](level,k,v))
--- end
--- elseif tk == "boolean" then
--- handle(formatters["%w [%S]=%s,"](level,k,v))
--- elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
--- handle(formatters["%w %s=%s,"](level,k,v))
--- else
--- handle(formatters["%w [%q]=%s,"](level,k,v))
--- end
--- else
--- if tk == "number" then
--- if hexify then
--- handle(formatters["%w [%04H]=%q,"](level,k,v))
--- else
--- handle(formatters["%w [%s]=%q,"](level,k,v))
--- end
--- elseif tk == "boolean" then
--- handle(formatters["%w [%S]=%q,"](level,k,v))
--- elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
--- handle(formatters["%w %s=%q,"](level,k,v))
--- else
--- handle(formatters["%w [%q]=%q,"](level,k,v))
--- end
--- end
--- elseif t == "table" then
--- if not next(v) then
--- if tk == "number" then
--- if hexify then
--- handle(formatters["%w [%04H]={},"](level,k))
--- else
--- handle(formatters["%w [%s]={},"](level,k))
--- end
--- elseif tk == "boolean" then
--- handle(formatters["%w [%S]={},"](level,k))
--- elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
--- handle(formatters["%w %s={},"](level,k))
--- else
--- handle(formatters["%w [%q]={},"](level,k))
--- end
--- elseif inline then
--- local st = simple_table(v)
--- if st then
--- if tk == "number" then
--- if hexify then
--- handle(formatters["%w [%04H]={ %, t },"](level,k,st))
--- else
--- handle(formatters["%w [%s]={ %, t },"](level,k,st))
--- end
--- elseif tk == "boolean" then
--- handle(formatters["%w [%S]={ %, t },"](level,k,st))
--- elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
--- handle(formatters["%w %s={ %, t },"](level,k,st))
--- else
--- handle(formatters["%w [%q]={ %, t },"](level,k,st))
--- end
--- else
--- do_serialize(v,k,level+1)
--- end
--- else
--- do_serialize(v,k,level+1)
--- end
--- elseif t == "boolean" then
--- if tk == "number" then
--- if hexify then
--- handle(formatters["%w [%04H]=%S,"](level,k,v))
--- else
--- handle(formatters["%w [%s]=%S,"](level,k,v))
--- end
--- elseif tk == "boolean" then
--- handle(formatters["%w [%S]=%S,"](level,k,v))
--- elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
--- handle(formatters["%w %s=%S,"](level,k,v))
--- else
--- handle(formatters["%w [%q]=%S,"](level,k,v))
--- end
--- elseif t == "function" then
--- if functions then
--- local f = getinfo(v).what == "C" and dump(dummy) or dump(v) -- maybe strip
--- -- local f = getinfo(v).what == "C" and dump(function(...) return v(...) end) or dump(v) -- maybe strip
--- if tk == "number" then
--- if hexify then
--- handle(formatters["%w [%04H]=load(%q),"](level,k,f))
--- else
--- handle(formatters["%w [%s]=load(%q),"](level,k,f))
--- end
--- elseif tk == "boolean" then
--- handle(formatters["%w [%S]=load(%q),"](level,k,f))
--- elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
--- handle(formatters["%w %s=load(%q),"](level,k,f))
--- else
--- handle(formatters["%w [%q]=load(%q),"](level,k,f))
--- end
--- end
--- else
--- if tk == "number" then
--- if hexify then
--- handle(formatters["%w [%04H]=%Q,"](level,k,v))
--- else
--- handle(formatters["%w [%s]=%Q,"](level,k,v))
--- end
--- elseif tk == "boolean" then
--- handle(formatters["%w [%S]=%Q,"](level,k,v))
--- elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
--- handle(formatters["%w %s=%Q,"](level,k,v))
--- else
--- handle(formatters["%w [%q]=%Q,"](level,k,v))
--- end
--- end
--- --~ end
--- end
--- end
--- if level > 0 then
--- handle(formatters["%w}"](level))
--- end
--- end
-
--- local function serialize(_handle,root,name,specification) -- handle wins
--- local tname = type(name)
--- if type(specification) == "table" then
--- noquotes = specification.noquotes
--- hexify = specification.hexify
--- handle = _handle or specification.handle or print
--- reduce = specification.reduce or false
--- functions = specification.functions
--- compact = specification.compact
--- inline = specification.inline and compact
--- if functions == nil then
--- functions = true
--- end
--- if compact == nil then
--- compact = true
--- end
--- if inline == nil then
--- inline = compact
--- end
--- else
--- noquotes = false
--- hexify = false
--- handle = _handle or print
--- reduce = false
--- compact = true
--- inline = true
--- functions = true
--- end
--- if tname == "string" then
--- if name == "return" then
--- handle("return {")
--- else
--- handle(name .. "={")
--- end
--- elseif tname == "number" then
--- if hexify then
--- handle(format("[0x%04X]={",name))
--- else
--- handle("[" .. name .. "]={")
--- end
--- elseif tname == "boolean" then
--- if name then
--- handle("return {")
--- else
--- handle("{")
--- end
--- else
--- handle("t={")
--- end
--- if root then
--- -- The dummy access will initialize a table that has a delayed initialization
--- -- using a metatable. (maybe explicitly test for metatable)
--- if getmetatable(root) then -- todo: make this an option, maybe even per subtable
--- local dummy = root._w_h_a_t_e_v_e_r_
--- root._w_h_a_t_e_v_e_r_ = nil
--- end
--- -- Let's forget about empty tables.
--- if next(root) then
--- do_serialize(root,name,0)
--- end
--- end
--- handle("}")
--- end
+-- A version with formatters is some 20% faster than using format (because formatters are
+-- much faster) but of course, inlining the format using .. is then again faster .. anyway,
+-- as we do some pretty printing as well there is not that much to gain unless we make a
+-- 'fast' ugly variant as well. But, we would have to move the formatter to l-string then.
-- name:
--
diff --git a/tex/context/base/lpdf-ano.lua b/tex/context/base/lpdf-ano.lua
index adfea3812..990e87abd 100644
--- a/tex/context/base/lpdf-ano.lua
+++ b/tex/context/base/lpdf-ano.lua
@@ -334,13 +334,38 @@ end
-- runners and specials
+-- runners["inner"] = function(var,actions)
+-- if getinnermethod() == "names" then
+-- local vi = var.i
+-- if vi then
+-- local vir = vi.references
+-- if vir then
+-- local internal = vir.internal
+-- if internal then
+-- var.inner = "aut:" .. internal
+-- end
+-- end
+-- end
+-- else
+-- var.inner = nil
+-- end
+-- local prefix = var.p
+-- local inner = var.inner
+-- if inner and prefix and prefix ~= "" then
+-- inner = prefix .. ":" .. inner -- might not always be ok
+-- end
+-- return link(nil,nil,inner,var.r,actions)
+-- end
+
runners["inner"] = function(var,actions)
+ local internal = false
if getinnermethod() == "names" then
local vi = var.i
if vi then
local vir = vi.references
if vir then
- local internal = vir.internal
+ -- todo: no need for it when we have a real reference
+ internal = vir.internal
if internal then
var.inner = "aut:" .. internal
end
@@ -351,8 +376,9 @@ runners["inner"] = function(var,actions)
end
local prefix = var.p
local inner = var.inner
- if inner and prefix and prefix ~= "" then
- inner = prefix .. ":" .. inner -- might not always be ok
+ if not internal and inner and prefix and prefix ~= "" then
+ -- no prefix with e.g. components
+ inner = prefix .. ":" .. inner
end
return link(nil,nil,inner,var.r,actions)
end
diff --git a/tex/context/base/math-act.lua b/tex/context/base/math-act.lua
index 4f9b3b7e8..ddc4de179 100644
--- a/tex/context/base/math-act.lua
+++ b/tex/context/base/math-act.lua
@@ -10,6 +10,7 @@ if not modules then modules = { } end modules ['math-act'] = {
local type, next = type, next
local fastcopy = table.fastcopy
+local formatters = string.formatters
local trace_defining = false trackers.register("math.defining", function(v) trace_defining = v end)
local report_math = logs.reporter("mathematics","initializing")
@@ -286,7 +287,7 @@ end
sequencers.appendaction("aftercopyingcharacters", "system","mathematics.overloaddimensions")
--- a couple of predefined tewaks:
+-- a couple of predefined tweaks:
local tweaks = { }
mathematics.tweaks = tweaks
@@ -295,6 +296,79 @@ function tweaks.fixbadprime(target,original)
target.characters[0xFE325] = target.characters[0x2032]
end
+local function accent_to_extensible(target,newchr,original,oldchr,height,depth)
+ local characters = target.characters
+-- if not characters[newchr] then
+ local olddata = characters[oldchr]
+ if olddata then
+ height = height or 0
+ depth = depth or 0
+ local addprivate = fonts.helpers.addprivate
+ local correction = { "down", olddata.height }
+ local newdata = {
+ commands = { correction, { "slot", 1, oldchr } },
+ width = olddata.width,
+ height = height,
+ depth = depth,
+ }
+ characters[newchr] = newdata
+ local nextglyph = olddata.next
+ while nextglyph do
+ local oldnextdata = characters[nextglyph]
+ local newnextdata = {
+ commands = { correction, { "slot", 1, nextglyph } },
+ width = oldnextdata.width,
+ height = height,
+ depth = depth,
+ }
+ local newnextglyph = addprivate(target,formatters["overline-%H"](nextglyph),newnextdata)
+ newdata.next = newnextglyph
+ local nextnextglyph = oldnextdata.next
+ if nextnextglyph == nextglyph then
+ break
+ else
+ olddata = oldnextdata
+ newdata = newnextdata
+ nextglyph = nextnextglyph
+ end
+ end
+ local hv = olddata.horiz_variants
+ if hv then
+ hv = fastcopy(hv)
+ newdata.horiz_variants = hv
+ for i=1,#hv do
+ local hvi = hv[i]
+ local oldglyph = hvi.glyph
+ local olddata = characters[oldglyph]
+ local newdata = {
+ commands = { correction, { "slot", 1, oldglyph } },
+ width = olddata.width,
+ height = height,
+ depth = depth,
+ }
+ hvi.glyph = addprivate(target,formatters["overline-%H"](oldglyph),newdata)
+ end
+ end
+ end
+-- end
+end
+
+function tweaks.fixoverline(target,original)
+ local height, depth = 0, 0
+ local mathparameters = target.mathparameters
+ if mathparameters then
+ height = mathparameters.OverbarVerticalGap
+ depth = mathparameters.UnderbarVerticalGap
+ else
+ height = target.parameters.xheight/4
+ depth = height
+ end
+ accent_to_extensible(target,0x203E,original,0x0305,height,depth)
+-- inspect(fonts.helpers.expandglyph(target.characters,0x203E))
+end
+
+sequencers.appendaction("aftercopyingcharacters", "system","mathematics.tweaks.fixoverline") -- for the moment always
+
-- helpers
local setmetatableindex = table.setmetatableindex
diff --git a/tex/context/base/math-ini.lua b/tex/context/base/math-ini.lua
index 076a56184..6e667d083 100644
--- a/tex/context/base/math-ini.lua
+++ b/tex/context/base/math-ini.lua
@@ -322,14 +322,14 @@ local function utfmathclass(chr, default)
return cd and cd.mathclass or default or "unknown"
end
-local function utfmathaccent(chr,default,asked)
+local function utfmathaccent(chr,default,asked1,asked2)
local cd = chardata[utfbyte(chr)]
if not cd then
return default or false
end
- if asked then
+ if asked1 and asked1 ~= "" then
local mc = cd.mathclass
- if mc and mc == asked then
+ if mc and (mc == asked1 or mc == asked2) then
return true
end
local ms = cd.mathspec
@@ -337,7 +337,7 @@ local function utfmathaccent(chr,default,asked)
for i=1,#ms do
local msi = ms[i]
local mc = msi.class
- if mc and mc == asked then
+ if mc and (mc == asked1 or mc == asked2) then
return true
end
end
@@ -366,7 +366,7 @@ local function utfmathstretch(chr, default) -- "h", "v", "b", ""
return cd and cd.mathstretch or default or ""
end
-local function utfmathcommand(chr,default,asked)
+local function utfmathcommand(chr,default,asked1,asked2)
-- local cd = chardata[utfbyte(chr)]
-- local cmd = cd and cd.mathname
-- return cmd or default or ""
@@ -374,10 +374,10 @@ local function utfmathcommand(chr,default,asked)
if not cd then
return default or ""
end
- if asked then
+ if asked1 then
local mn = cd.mathname
local mc = cd.mathclass
- if mn and mc and mc == asked then
+ if mn and mc and (mc == asked1 or mc == asked2) then
return mn
end
local ms = cd.mathspec
@@ -385,7 +385,7 @@ local function utfmathcommand(chr,default,asked)
for i=1,#ms do
local msi = ms[i]
local mn = msi.name
- if mn and msi.class == asked then
+ if mn and (msi.class == asked1 or msi.class == asked2) then
return mn
end
end
@@ -431,6 +431,17 @@ function commands.doifelseutfmathaccent(chr,asked)
commands.doifelse(utfmathaccent(chr,nil,asked))
end
+function commands.utfmathcommandabove(asked) context(utfmathcommand(asked,nil,"topaccent","over" )) end
+function commands.utfmathcommandbelow(asked) context(utfmathcommand(asked,nil,"botaccent","under")) end
+
+function commands.doifelseutfmathabove(chr)
+ commands.doifelse(utfmathaccent(chr,nil,asked,"topaccent","over"))
+end
+
+function commands.doifelseutfmathbelow(chr)
+ commands.doifelse(utfmathaccent(chr,nil,asked,"botaccent","under"))
+end
+
-- helpers
function mathematics.big(tfmdata,unicode,n)
diff --git a/tex/context/base/math-ini.mkiv b/tex/context/base/math-ini.mkiv
index 81ec339d6..d777bb018 100644
--- a/tex/context/base/math-ini.mkiv
+++ b/tex/context/base/math-ini.mkiv
@@ -277,9 +277,15 @@
\def\utfmathclassfiltered #1#2{\ctxcommand{utfmathclass (\!!bs#1\!!es,nil,"#2")}}
\def\utfmathcommandfiltered#1#2{\ctxcommand{utfmathcommand(\!!bs#1\!!es,nil,"#2")}}
+\def\utfmathcommandabove#1{\ctxcommand{utfmathcommandabove(\!!bs#1\!!es)}}
+\def\utfmathcommandbelow#1{\ctxcommand{utfmathcommandbelow(\!!bs#1\!!es)}}
+
\unexpanded\def\doifelseutfmathaccent #1{\ctxcommand{doifelseutfmathaccent(\!!bs#1\!!es)}}
\unexpanded\def\doifelseutfmathaccentfiltered#1#2{\ctxcommand{doifelseutfmathaccent(\!!bs#1\!!es,"#2")}}
+\unexpanded\def\doifelseutfmathabove #1{\ctxcommand{doifelseutfmathabove(\!!bs#1\!!es)}}
+\unexpanded\def\doifelseutfmathbelow #1{\ctxcommand{doifelseutfmathbelow(\!!bs#1\!!es)}}
+
%D Not used that much:
\installcorenamespace{mathcodecommand}
diff --git a/tex/context/base/math-stc.mkvi b/tex/context/base/math-stc.mkvi
index 2dc2b2c22..8d5b1d18f 100644
--- a/tex/context/base/math-stc.mkvi
+++ b/tex/context/base/math-stc.mkvi
@@ -568,7 +568,7 @@
\definemathstackers
[\v!bottom]
[\v!mathematics]
- [\c!location=\v!top,
+ [\c!location=\v!top, % ?
\c!strut=\v!no,
\c!middlecommand=\mathematics,
\c!hoffset=\zeropoint]
@@ -667,6 +667,22 @@
\definemathunderextensible [\v!bottom] [undertwoheadleftarrow] ["27F8]
\definemathunderextensible [\v!bottom] [undertwoheadrightarrow] ["27F9]
+% We don't use overline and underline. This is one of the overlooked aspects of
+% unicode cq. opentype math: why treat rules different than e.g. arrows and
+% accents. It is a bit unfortunate that the opportunity to move math to new
+% technologies happened outside the tex domain (and/or some aspects were kept
+% while in fact they were side effects of limitations of traditional fonts).
+% From the unicode aware tex engines' implementation point of view things
+% could have been done a bit nicer but then: the community didn't seem to care
+% too much and just has to follow now.
+%
+% Anyhow, we use a character based approach so that at least we get unicode
+% stuff in the backend (okay, we still need to deal with some cut and paste
+% issues but at least we now know what we deal with.
+
+\definemathunderextensible [\v!bottom] [underbar] ["203E]
+\definemathoverextensible [\v!top] [overbar] ["203E]
+
%D Some bonus ones (for the moment here):
\definemathstackers
diff --git a/tex/context/base/node-fin.lua b/tex/context/base/node-fin.lua
index 2e62ebcb5..63a5ef83e 100644
--- a/tex/context/base/node-fin.lua
+++ b/tex/context/base/node-fin.lua
@@ -41,93 +41,13 @@ local unsetvalue = attributes.unsetvalue
-- these two will be like trackers
-function states.enabletriggering()
- triggering = true
-end
-function states.disabletriggering()
- triggering = false
-end
-
--- the following code is no longer needed due to the new backend
--- but we keep it around for a while as an example
---
--- states.collected = states.collected or { }
---
--- storage.register("states/collected", states.collected, "states.collected")
---
--- local collected = states.collected
---
--- function states.collect(str)
--- collected[#collected+1] = str
--- end
---
--- function states.flush()
--- if #collected > 0 then
--- for i=1,#collected do
--- context(collected[i]) -- we're in context mode anyway
--- end
--- collected = { }
--- states.collected = collected
--- end
--- end
---
--- function states.check()
--- logs.report("states",concat(collected,"\n"))
--- end
-
--- we used to do the main processor loop here and call processor for each node
--- but eventually this was too much a slow down (1 sec on 23 for 120 pages mk)
--- so that we moved looping to the processor itself; this may lead to a bit of
--- duplicate code once that we have more state handlers
-
--- local function process_attribute(head,plugin) -- head,attribute,enabled,initializer,resolver,processor,finalizer
--- local namespace = plugin.namespace
--- if namespace.enabled ~= false then -- this test will go away
--- starttiming(attributes) -- in principle we could delegate this to the main caller
--- local done, used, ok = false, nil, false
--- local attribute = namespace.attribute or numbers[plugin.name] -- todo: plugin.attribute
--- local processor = plugin.processor
--- if processor then
--- local initializer = plugin.initializer
--- local resolver = plugin.resolver
--- local inheritance = (resolver and resolver()) or nil -- -0x7FFFFFFF -- we can best use nil and skip !
--- if initializer then
--- initializer(namespace,attribute,head)
--- end
--- head, ok = processor(namespace,attribute,head,inheritance)
--- if ok then
--- local finalizer = plugin.finalizer
--- if finalizer then
--- head, ok, used = finalizer(namespace,attribute,head)
--- if used then
--- local flusher = plugin.flusher
--- if flusher then
--- head = flusher(namespace,attribute,head,used)
--- end
--- end
--- end
--- done = true
--- end
--- end
--- stoptiming(attributes)
--- return head, done
--- else
--- return head, false
--- end
--- end
---
--- function nodes.installattributehandler(plugin) -- we need to avoid this nested function
--- return function(head)
--- return process_attribute(head,plugin)
--- end
--- end
-
--- An experiment: lean and mean functions. It is not really faster but
--- with upcoming functionality it might make a difference, e.g. features
--- like 'casing' and 'italics' can be called a lot so there it makes sense.
+function states.enabletriggering () triggering = true end
+function states.disabletriggering() triggering = false end
nodes.plugindata = nil
+-- inheritance: -0x7FFFFFFF -- we can best use nil and skip !
+
local template = [[
local plugin = nodes.plugindata
local starttiming = statistics.starttiming
@@ -146,8 +66,10 @@ if not processor then
elseif initializer or finalizer or resolver then
return function(head)
starttiming(attributes)
- local done, used, ok = false, nil, false
- local inheritance = (resolver and resolver()) or nil -- -0x7FFFFFFF -- we can best use nil and skip !
+ local done, used, ok, inheritance = false, nil, false, nil
+ if resolver then
+ inheritance = resolver()
+ end
if initializer then
initializer(namespace,attribute,head)
end
@@ -228,309 +150,6 @@ end
-- we need to deal with literals too (reset as well as oval)
-- if id == glyph_code or (id == whatsit_code and stack.subtype == pdfliteral_code) or (id == rule_code and stack.width ~= 0) or (id == glue_code and stack.leader) then
--- local function process(namespace,attribute,head,inheritance,default) -- one attribute
--- local stack, done = head, false
--- while stack do
--- local id = stack.id
--- if id == glyph_code or (id == rule_code and stack.width ~= 0) or (id == glue_code and stack.leader) then -- or disc_code
--- local c = stack[attribute]
--- if c then
--- if default and c == inheritance then
--- if current ~= default then
--- head = insert_node_before(head,stack,copy_node(nsdata[default]))
--- current = default
--- done = true
--- end
--- elseif current ~= c then
--- head = insert_node_before(head,stack,copy_node(nsdata[c]))
--- current = c
--- done = true
--- end
--- -- here ? compare selective
--- if id == glue_code then --leader
--- -- same as *list
--- local content = stack.leader
--- if content then
--- local savedcurrent = current
--- local ci = content.id
--- if ci == hlist_code or ci == vlist_code then
--- -- else we reset inside a box unneeded, okay, the downside is
--- -- that we trigger color in each repeated box, so there is room
--- -- for improvement here
--- current = 0
--- end
--- local ok = false
--- if nstrigger and stack[nstrigger] then
--- local outer = stack[attribute]
--- if outer ~= inheritance then
--- stack.leader, ok = process(namespace,attribute,content,inheritance,outer)
--- else
--- stack.leader, ok = process(namespace,attribute,content,inheritance,default)
--- end
--- else
--- stack.leader, ok = process(namespace,attribute,content,inheritance,default)
--- end
--- current = savedcurrent
--- done = done or ok
--- end
--- end
--- elseif default and inheritance then
--- if current ~= default then
--- head = insert_node_before(head,stack,copy_node(nsdata[default]))
--- current = default
--- done = true
--- end
--- elseif current > 0 then
--- head = insert_node_before(head,stack,copy_node(nsnone))
--- current = 0
--- done = true
--- end
--- elseif id == hlist_code or id == vlist_code then
--- local content = stack.list
--- if content then
--- local ok = false
--- if nstrigger and stack[nstrigger] then
--- local outer = stack[attribute]
--- if outer ~= inheritance then
--- stack.list, ok = process(namespace,attribute,content,inheritance,outer)
--- else
--- stack.list, ok = process(namespace,attribute,content,inheritance,default)
--- end
--- else
--- stack.list, ok = process(namespace,attribute,content,inheritance,default)
--- end
--- done = done or ok
--- end
--- end
--- stack = stack.next
--- end
--- return head, done
--- end
-
--- local function process(namespace,attribute,head,inheritance,default) -- one attribute
--- local stack, done = head, false
-
--- local function check()
--- local c = stack[attribute]
--- if c then
--- if default and c == inheritance then
--- if current ~= default then
--- head = insert_node_before(head,stack,copy_node(nsdata[default]))
--- current = default
--- done = true
--- end
--- elseif current ~= c then
--- head = insert_node_before(head,stack,copy_node(nsdata[c]))
--- current = c
--- done = true
--- end
--- elseif default and inheritance then
--- if current ~= default then
--- head = insert_node_before(head,stack,copy_node(nsdata[default]))
--- current = default
--- done = true
--- end
--- elseif current > 0 then
--- head = insert_node_before(head,stack,copy_node(nsnone))
--- current = 0
--- done = true
--- end
--- return c
--- end
-
--- local function nested(content)
--- if nstrigger and stack[nstrigger] then
--- local outer = stack[attribute]
--- if outer ~= inheritance then
--- return process(namespace,attribute,content,inheritance,outer)
--- else
--- return process(namespace,attribute,content,inheritance,default)
--- end
--- else
--- return process(namespace,attribute,content,inheritance,default)
--- end
--- end
-
--- while stack do
--- local id = stack.id
--- if id == glyph_code then
--- check()
--- elseif id == glue_code then
--- local content = stack.leader
--- if content and check() then
--- local savedcurrent = current
--- local ci = content.id
--- if ci == hlist_code or ci == vlist_code then
--- -- else we reset inside a box unneeded, okay, the downside is
--- -- that we trigger color in each repeated box, so there is room
--- -- for improvement here
--- current = 0
--- end
-
--- local ok = false
--- stack.leader, ok = nested(content)
--- done = done or ok
-
--- current = savedcurrent
--- end
--- elseif id == hlist_code or id == vlist_code then
--- local content = stack.list
--- if content then
-
--- local ok = false
--- stack.list, ok = nested(content)
--- done = done or ok
-
--- end
--- elseif id == rule_code then
--- if stack.width ~= 0 then
--- check()
--- end
--- end
--- stack = stack.next
--- end
--- return head, done
--- end
-
--- local function process(namespace,attribute,head,inheritance,default) -- one attribute
--- local stack, done = head, false
--- while stack do
--- local id = stack.id
--- if id == glyph_code then
--- -- begin of check
--- local c = stack[attribute]
--- if c then
--- if default and c == inheritance then
--- if current ~= default then
--- head = insert_node_before(head,stack,copy_node(nsdata[default]))
--- current = default
--- done = true
--- end
--- elseif current ~= c then
--- head = insert_node_before(head,stack,copy_node(nsdata[c]))
--- current = c
--- done = true
--- end
--- elseif default and inheritance then
--- if current ~= default then
--- head = insert_node_before(head,stack,copy_node(nsdata[default]))
--- current = default
--- done = true
--- end
--- elseif current > 0 then
--- head = insert_node_before(head,stack,copy_node(nsnone))
--- current = 0
--- done = true
--- end
--- -- end of check
--- elseif id == glue_code then
--- local content = stack.leader
--- if content then
--- -- begin of check
--- local c = stack[attribute]
--- if c then
--- if default and c == inheritance then
--- if current ~= default then
--- head = insert_node_before(head,stack,copy_node(nsdata[default]))
--- current = default
--- done = true
--- end
--- elseif current ~= c then
--- head = insert_node_before(head,stack,copy_node(nsdata[c]))
--- current = c
--- done = true
--- end
--- -- begin special to this check
--- local savedcurrent = current
--- local ci = content.id
--- if ci == hlist_code or ci == vlist_code then
--- -- else we reset inside a box unneeded, okay, the downside is
--- -- that we trigger color in each repeated box, so there is room
--- -- for improvement here
--- current = 0
--- end
--- -- begin nested --
--- local ok = false
--- if nstrigger and stack[nstrigger] then
--- local outer = stack[attribute]
--- if outer ~= inheritance then
--- stack.leader, ok = process(namespace,attribute,content,inheritance,outer)
--- else
--- stack.leader, ok = process(namespace,attribute,content,inheritance,default)
--- end
--- else
--- stack.leader, ok = process(namespace,attribute,content,inheritance,default)
--- end
--- -- end nested --
--- done = done or ok
--- current = savedcurrent
--- -- end special to this check
--- elseif default and inheritance then
--- if current ~= default then
--- head = insert_node_before(head,stack,copy_node(nsdata[default]))
--- current = default
--- done = true
--- end
--- elseif current > 0 then
--- head = insert_node_before(head,stack,copy_node(nsnone))
--- current = 0
--- done = true
--- end
--- -- end of check
--- end
--- elseif id == hlist_code or id == vlist_code then
--- local content = stack.list
--- if content then
--- -- begin nested --
--- local ok
--- if nstrigger and stack[nstrigger] then
--- local outer = stack[attribute]
--- if outer ~= inheritance then
--- stack.list, ok = process(namespace,attribute,content,inheritance,outer)
--- else
--- stack.list, ok = process(namespace,attribute,content,inheritance,default)
--- end
--- else
--- stack.list, ok = process(namespace,attribute,content,inheritance,default)
--- end
--- -- end nested --
--- done = done or ok
--- end
--- elseif id == rule_code then
--- if stack.width ~= 0 then
--- -- begin of check
--- local c = stack[attribute]
--- if c then
--- if default and c == inheritance then
--- if current ~= default then
--- head = insert_node_before(head,stack,copy_node(nsdata[default]))
--- current = default
--- done = true
--- end
--- elseif current ~= c then
--- head = insert_node_before(head,stack,copy_node(nsdata[c]))
--- current = c
--- done = true
--- end
--- elseif default and inheritance then
--- if current ~= default then
--- head = insert_node_before(head,stack,copy_node(nsdata[default]))
--- current = default
--- done = true
--- end
--- elseif current > 0 then
--- head = insert_node_before(head,stack,copy_node(nsnone))
--- current = 0
--- done = true
--- end
--- -- end of check
--- end
--- end
--- stack = stack.next
--- end
--- return head, done
--- end
-
local function process(namespace,attribute,head,inheritance,default) -- one attribute
local stack = head
local done = false
@@ -633,184 +252,6 @@ states.process = process
-- state changes while the main state stays the same (like two glyphs following
-- each other with the same color but different color spaces e.g. \showcolor)
--- local function selective(namespace,attribute,head,inheritance,default) -- two attributes
--- local stack, done = head, false
--- while stack do
--- local id = stack.id
--- -- we need to deal with literals too (reset as well as oval)
--- -- if id == glyph_code or (id == whatsit_code and stack.subtype == pdfliteral_code) or (id == rule_code and stack.width ~= 0) or (id == glue_code and stack.leader) then -- or disc_code
--- if id == glyph_code -- or id == disc_code
--- or (id == rule_code and stack.width ~= 0) or (id == glue_code and stack.leader) then -- or disc_code
--- local c = stack[attribute]
--- if c then
--- if default and c == inheritance then
--- if current ~= default then
--- local data = nsdata[default]
--- head = insert_node_before(head,stack,copy_node(data[nsforced or stack[nsselector] or nsselector]))
--- current = default
--- done = true
--- end
--- else
--- local s = stack[nsselector]
--- if current ~= c or current_selector ~= s then
--- local data = nsdata[c]
--- head = insert_node_before(head,stack,copy_node(data[nsforced or stack[nsselector] or nsselector]))
--- current = c
--- current_selector = s
--- done = true
--- end
--- end
--- elseif default and inheritance then
--- if current ~= default then
--- local data = nsdata[default]
--- head = insert_node_before(head,stack,copy_node(data[nsforced or stack[nsselector] or nsselector]))
--- current = default
--- done = true
--- end
--- elseif current > 0 then
--- head = insert_node_before(head,stack,copy_node(nsnone))
--- current, current_selector, done = 0, 0, true
--- end
--- if id == glue_code then -- leader
--- -- same as *list
--- local content = stack.leader
--- if content then
--- local savedcurrent = current
--- local ci = content.id
--- if ci == hlist_code or ci == vlist_code then
--- -- else we reset inside a box unneeded, okay, the downside is
--- -- that we trigger color in each repeated box, so there is room
--- -- for improvement here
--- current = 0
--- end
--- local ok = false
--- if nstrigger and stack[nstrigger] then
--- local outer = stack[attribute]
--- if outer ~= inheritance then
--- stack.leader, ok = selective(namespace,attribute,content,inheritance,outer)
--- else
--- stack.leader, ok = selective(namespace,attribute,content,inheritance,default)
--- end
--- else
--- stack.leader, ok = selective(namespace,attribute,content,inheritance,default)
--- end
--- current = savedcurrent
--- done = done or ok
--- end
--- end
--- elseif id == hlist_code or id == vlist_code then
--- local content = stack.list
--- if content then
--- local ok = false
--- if nstrigger and stack[nstrigger] then
--- local outer = stack[attribute]
--- if outer ~= inheritance then
--- stack.list, ok = selective(namespace,attribute,content,inheritance,outer)
--- else
--- stack.list, ok = selective(namespace,attribute,content,inheritance,default)
--- end
--- else
--- stack.list, ok = selective(namespace,attribute,content,inheritance,default)
--- end
--- done = done or ok
--- end
--- end
--- stack = stack.next
--- end
--- return head, done
--- end
-
--- local function selective(namespace,attribute,head,inheritance,default) -- two attributes
--- local stack, done = head, false
-
--- local function check()
--- local c = stack[attribute]
--- if c then
--- if default and c == inheritance then
--- if current ~= default then
--- local data = nsdata[default]
--- head = insert_node_before(head,stack,copy_node(data[nsforced or stack[nsselector] or nsselector]))
--- current = default
--- done = true
--- end
--- else
--- local s = stack[nsselector]
--- if current ~= c or current_selector ~= s then
--- local data = nsdata[c]
--- head = insert_node_before(head,stack,copy_node(data[nsforced or stack[nsselector] or nsselector]))
--- current = c
--- current_selector = s
--- done = true
--- end
--- end
--- elseif default and inheritance then
--- if current ~= default then
--- local data = nsdata[default]
--- head = insert_node_before(head,stack,copy_node(data[nsforced or stack[nsselector] or nsselector]))
--- current = default
--- done = true
--- end
--- elseif current > 0 then
--- head = insert_node_before(head,stack,copy_node(nsnone))
--- current, current_selector, done = 0, 0, true
--- end
--- return c
--- end
-
--- local function nested(content)
--- if nstrigger and stack[nstrigger] then
--- local outer = stack[attribute]
--- if outer ~= inheritance then
--- return selective(namespace,attribute,content,inheritance,outer)
--- else
--- return selective(namespace,attribute,content,inheritance,default)
--- end
--- else
--- return selective(namespace,attribute,content,inheritance,default)
--- end
--- end
-
--- while stack do
--- local id = stack.id
--- if id == glyph_code then
--- check()
--- elseif id == glue_code then
--- local content = stack.leader
--- if content and check() then
--- -- local savedcurrent = current
--- -- local ci = content.id
--- -- if ci == hlist_code or ci == vlist_code then
--- -- -- else we reset inside a box unneeded, okay, the downside is
--- -- -- that we trigger color in each repeated box, so there is room
--- -- -- for improvement here
--- -- current = 0
--- -- end
-
--- local ok = false
--- stack.leader, ok = nested(content)
--- done = done or ok
-
--- -- current = savedcurrent
--- end
--- elseif id == hlist_code or id == vlist_code then
--- local content = stack.list
--- if content then
-
--- local ok = false
--- stack.list, ok = nested(content)
--- done = done or ok
-
--- end
--- elseif id == rule_code then
--- if stack.width ~= 0 then
--- check()
--- end
--- end
--- stack = stack.next
--- end
--- return head, done
--- end
-
local function selective(namespace,attribute,head,inheritance,default) -- two attributes
local stack = head
local done = false
@@ -914,77 +355,6 @@ states.selective = selective
-- Todo: make a better stacker. Keep track (in attribute) about nesting level. Not
-- entirely trivial and a generic solution is nicer (compares to the exporter).
--- local function stacked(namespace,attribute,head,default) -- no triggering, no inheritance, but list-wise
--- local stack, done = head, false
--- local current, depth = default or 0, 0
---
--- local function check()
--- local a = stack[attribute]
--- if a then
--- if current ~= a then
--- head = insert_node_before(head,stack,copy_node(nsdata[a]))
--- depth = depth + 1
--- current, done = a, true
--- end
--- elseif default > 0 then
--- --
--- elseif current > 0 then
--- head = insert_node_before(head,stack,copy_node(nsnone))
--- depth = depth - 1
--- current, done = 0, true
--- end
--- return a
--- end
---
--- while stack do
--- local id = stack.id
--- if id == glyph_code then
--- check()
--- elseif id == glue_code then
--- local content = stack.leader
--- if content and check() then
--- local ok = false
--- stack.leader, ok = stacked(namespace,attribute,content,current)
--- done = done or ok
--- end
--- elseif id == hlist_code or id == vlist_code then
--- local content = stack.list
--- if content then
--- -- the problem is that broken lines gets the attribute which can be a later one
--- if nslistwise then
--- local a = stack[attribute]
--- if a and current ~= a and nslistwise[a] then -- viewerlayer / needs checking, see below
--- local p = current
--- current, done = a, true
--- head = insert_node_before(head,stack,copy_node(nsdata[a]))
--- stack.list = stacked(namespace,attribute,content,current)
--- head, stack = insert_node_after(head,stack,copy_node(nsnone))
--- current = p
--- else
--- local ok = false
--- stack.list, ok = stacked(namespace,attribute,content,current)
--- done = done or ok
--- end
--- else
--- local ok = false
--- stack.list, ok = stacked(namespace,attribute,content,current)
--- done = done or ok
--- end
--- end
--- elseif id == rule_code then
--- if stack.width ~= 0 then
--- check()
--- end
--- end
--- stack = stack.next
--- end
--- while depth > 0 do
--- head = insert_node_after(head,stack,copy_node(nsnone))
--- depth = depth - 1
--- end
--- return head, done
--- end
-
local function stacked(namespace,attribute,head,default) -- no triggering, no inheritance, but list-wise
local stack = head
local done = false
@@ -1066,76 +436,6 @@ states.stacked = stacked
-- experimental
--- local function stacker(namespace,attribute,head,default) -- no triggering, no inheritance, but list-wise
--- nsbegin()
--- local current, previous, done, okay = head, head, false, false
--- local attrib = default or unsetvalue
---
--- local function check()
--- local a = current[attribute] or unsetvalue
--- if a ~= attrib then
--- local n = nsstep(a)
--- if n then
--- -- !!!! TEST CODE !!!!
--- -- head = insert_node_before(head,current,copy_node(nsdata[tonumber(n)])) -- a
--- head = insert_node_before(head,current,n) -- a
--- end
--- attrib, done, okay = a, true, true
--- end
--- return a
--- end
---
--- while current do
--- local id = current.id
--- if id == glyph_code then
--- check()
--- elseif id == glue_code then
--- local content = current.leader
--- if content and check() then
--- -- tricky as a leader has to be a list so we cannot inject before
--- local _, ok = stacker(namespace,attribute,content,attrib)
--- done = done or ok
--- end
--- elseif id == hlist_code or id == vlist_code then
--- local content = current.list
--- if not content then
--- -- skip
--- elseif nslistwise then
--- local a = current[attribute]
--- if a and attrib ~= a and nslistwise[a] then -- viewerlayer
--- done = true
--- head = insert_node_before(head,current,copy_node(nsdata[a]))
--- current.list = stacker(namespace,attribute,content,a)
--- head, current = insert_node_after(head,current,copy_node(nsnone))
--- else
--- local ok = false
--- current.list, ok = stacker(namespace,attribute,content,attrib)
--- done = done or ok
--- end
--- else
--- local ok = false
--- current.list, ok = stacker(namespace,attribute,content,default)
--- done = done or ok
--- end
--- elseif id == rule_code then
--- if current.width ~= 0 then
--- check()
--- end
--- end
--- previous = current
--- current = current.next
--- end
--- if okay then
--- local n = nsend()
--- if n then
--- -- !!!! TEST CODE !!!!
--- -- head = insert_node_after(head,previous,copy_node(nsdata[tostring(n)]))
--- head = insert_node_after(head,previous,n)
--- end
--- end
--- return head, done
--- end
-
local function stacker(namespace,attribute,head,default) -- no triggering, no inheritance, but list-wise
nsbegin()
local current = head
diff --git a/tex/context/base/node-pro.lua b/tex/context/base/node-pro.lua
index 7bfcf6d4a..b98292abb 100644
--- a/tex/context/base/node-pro.lua
+++ b/tex/context/base/node-pro.lua
@@ -118,6 +118,9 @@ local enabled = true
function processors.hpack_filter(head,groupcode,size,packtype,direction)
if enabled then
+ -- if not head.next and head.id ~= glyph_code then -- happens often but not faster
+ -- return true
+ -- end
local first, found = first_glyph(head) -- they really need to be glyphs
if found then
if trace_callbacks then
diff --git a/tex/context/base/node-rul.mkiv b/tex/context/base/node-rul.mkiv
index 640cc54fe..2d2e61134 100644
--- a/tex/context/base/node-rul.mkiv
+++ b/tex/context/base/node-rul.mkiv
@@ -185,9 +185,14 @@
% \definebar[touchbar] [\c!method=0,\c!dy=-0.4,\c!offset=-0.0]
% \definebar[touchbars] [touchbar] [\c!continue=\v!yes]
-\definebar[\v!overstrike][\c!method=0,\c!dy=0.4,\c!offset=0.5,\c!continue=\v!yes]
-\definebar[\v!underbar] [\c!method=1,\c!dy=-0.4,\c!offset=-0.3,\c!continue=\v!yes]
+\let\normalmathoverbar \overbar
+\let\normalmathunderbar \underbar
+\let\normalmathoverstrike \overstrike
+\let\normalmathunderstrike\understrike
+
\definebar[\v!overbar] [\c!method=1,\c!dy=0.4,\c!offset=1.8,\c!continue=\v!yes]
+\definebar[\v!underbar] [\c!method=1,\c!dy=-0.4,\c!offset=-0.3,\c!continue=\v!yes]
+\definebar[\v!overstrike][\c!method=0,\c!dy=0.4,\c!offset=0.5,\c!continue=\v!yes]
\definebar
[\v!understrike]
@@ -198,16 +203,41 @@
\c!order=\v!background,
\c!color=lightgray]
-\definebar[\v!overstrikes] [\v!overstrike] [\c!continue=\v!no]
-\definebar[\v!underbars] [\v!underbar] [\c!continue=\v!no]
\definebar[\v!overbars] [\v!overbar] [\c!continue=\v!no]
+\definebar[\v!underbars] [\v!underbar] [\c!continue=\v!no]
+\definebar[\v!overstrikes] [\v!overstrike] [\c!continue=\v!no]
\definebar[\v!understrikes][\v!understrike][\c!continue=\v!no]
% we want these always so ...
-\expandafter\let\expandafter\overstrike \csname\v!overstrike \endcsname
-\expandafter\let\expandafter\underbar \csname\v!underbar \endcsname
-\expandafter\let\expandafter\overbar \csname\v!overbar \endcsname
+\ifdefined\normalmathunderbar
+ \expandafter\let\expandafter\normaltextunderbar\csname\v!underbar\endcsname
+ \unexpanded\def\underbar{\mathortext\normalmathunderbar\normaltextunderbar}
+\else
+ \expandafter\let\expandafter\underbar\csname\v!underbar\endcsname
+\fi
+
+\ifdefined\normalmathoverbar
+ \expandafter\let\expandafter\normaltextoverbar\csname\v!overbar\endcsname
+ \unexpanded\def\overbar{\mathortext\normalmathoverbar\normaltextoverbar}
+\else
+ \expandafter\let\expandafter\overbar\csname\v!overbar\endcsname
+\fi
+
+\ifdefined\normalmathunderstrike
+ \expandafter\let\expandafter\normaltextunderstrike\csname\v!understrike\endcsname
+ \unexpanded\def\understrike{\mathortext\normalmathunderstrike\normaltextunderstrike}
+\else
+ \expandafter\let\expandafter\understrike\csname\v!understrike\endcsname
+\fi
+
+\ifdefined\normalmathoverstrike
+ \expandafter\let\expandafter\normaltextoverstrike\csname\v!overstrike\endcsname
+ \unexpanded\def\overstrike{\mathortext\normalmathoverstrike \normaltextoverstrike}
+\else
+ \expandafter\let\expandafter\overstrike\csname\v!overstrike\endcsname
+\fi
+
\expandafter\let\expandafter\overstrikes\csname\v!overstrikes\endcsname
\expandafter\let\expandafter\underbars \csname\v!underbars \endcsname
\expandafter\let\expandafter\overbars \csname\v!overbars \endcsname
diff --git a/tex/context/base/spac-ver.mkiv b/tex/context/base/spac-ver.mkiv
index ee78d8964..9b74b273a 100644
--- a/tex/context/base/spac-ver.mkiv
+++ b/tex/context/base/spac-ver.mkiv
@@ -913,7 +913,7 @@
\s!depth \strutdp}}
\def\spac_struts_set_vide
- {\setbox\strutbox\hbox
+ {\setbox\strutbox\hbox % at some time this extra wrapping was needed
{\spac_struts_vide_hbox to \zeropoint
{% \hss % new, will be option
\vrule
@@ -939,8 +939,8 @@
\unexpanded\def\strut % still callbacks for \hbox{\strut}
{\relax
- \dontleavehmode
- \copy\strutbox}
+ \dontleavehmode
+ \copy\strutbox}
\let\normalstrut\strut
diff --git a/tex/context/base/status-files.pdf b/tex/context/base/status-files.pdf
index c4de827c9..022b6158e 100644
--- a/tex/context/base/status-files.pdf
+++ b/tex/context/base/status-files.pdf
Binary files differ
diff --git a/tex/context/base/status-lua.pdf b/tex/context/base/status-lua.pdf
index 1c9fabde3..8c4c25ffa 100644
--- a/tex/context/base/status-lua.pdf
+++ b/tex/context/base/status-lua.pdf
Binary files differ
diff --git a/tex/context/base/strc-ref.lua b/tex/context/base/strc-ref.lua
index 03ae94823..8e65a6b19 100644
--- a/tex/context/base/strc-ref.lua
+++ b/tex/context/base/strc-ref.lua
@@ -1799,7 +1799,7 @@ function filters.generic.number(data,what,prefixspec) -- todo: spec and then no
sections.typesetnumber(numberdata,"number",numberdata)
else
local useddata = data.useddata
- if useddata and useddsta.number then
+ if useddata and useddata.number then
context(useddata.number)
end
end
diff --git a/tex/context/base/trac-vis.lua b/tex/context/base/trac-vis.lua
index df4909c3e..762c71ab5 100644
--- a/tex/context/base/trac-vis.lua
+++ b/tex/context/base/trac-vis.lua
@@ -158,7 +158,7 @@ local preset_all = preset_makeup + modes.fontkern + modes.whatsit + modes.gly
function visualizers.setfont(id)
usedfont = id or current_font()
exheight = exheights[usedfont]
- emwidth = emwidths[usedfont]
+ emwidth = emwidths[usedfont]
end
-- we can preset a bunch of bits
@@ -204,18 +204,12 @@ local function setvisual(n,a,what) -- this will become more efficient when we ha
a = preset_makeup
else
a = setbit(a,preset_makeup)
- -- for i=1,#modes_makeup do
- -- a = setvisual(modes_makeup[i],a)
- -- end
end
elseif n == "boxes" then
if not a or a == 0 or a == unsetvalue then
a = preset_boxes
else
a = setbit(a,preset_boxes)
- -- for i=1,#modes_boxes do
- -- a = setvisual(modes_boxes[i],a)
- -- end
end
elseif n == "all" then
if what == false then
@@ -224,9 +218,6 @@ local function setvisual(n,a,what) -- this will become more efficient when we ha
a = preset_all
else
a = setbit(a,preset_all)
- -- for i=1,#modes_all do
- -- a = setvisual(modes_all[i],a)
- -- end
end
else
local m = modes[n]
@@ -522,12 +513,12 @@ local function ruledbox(head,current,vertical,layer,what,simple)
next.prev = info
end
if prev then
-if prev.id == gluespec_code then
- -- weird, how can this happen, an inline glue-spec
-else
- info.prev = prev
- prev.next = info
-end
+ if prev.id == gluespec_code then
+ -- weird, how can this happen, an inline glue-spec
+ else
+ info.prev = prev
+ prev.next = info
+ end
end
if head == current then
return info, info
@@ -552,6 +543,7 @@ local function ruledglyph(head,current)
end
local doublelinewidth = 2*linewidth
local info = concat_nodes {
+ -- could be a pdf rule
new_rule(linewidth,ht,dp),
new_rule(wd-doublelinewidth,-dp+linewidth,dp),
new_rule(linewidth,ht,dp),
diff --git a/tex/context/base/util-str.lua b/tex/context/base/util-str.lua
index 10456a729..0c8c0e2d2 100644
--- a/tex/context/base/util-str.lua
+++ b/tex/context/base/util-str.lua
@@ -735,11 +735,17 @@ strings.formatters.add = add
-- registered in the default instance (should we fall back on this one?)
-lpeg.patterns.xmlescape = Cs((P("<")/"&lt;" + P(">")/"&gt;" + P("&")/"&amp;" + P('"')/"&quot;" + P(1))^0)
-lpeg.patterns.texescape = Cs((C(S("#$%\\{}"))/"\\%1" + P(1))^0)
+patterns.xmlescape = Cs((P("<")/"&lt;" + P(">")/"&gt;" + P("&")/"&amp;" + P('"')/"&quot;" + P(1))^0)
+patterns.texescape = Cs((C(S("#$%\\{}"))/"\\%1" + P(1))^0)
+patterns.luaescape = Cs(((1-S('"\n'))^1 + P('"')/'\\"' + P('\n')/'\\n"')^0) -- maybe also \0
+patterns.luaquoted = Cs(Cc('"') * ((1-S('"\n'))^1 + P('"')/'\\"' + P('\n')/'\\n"')^0 * Cc('"'))
-add(formatters,"xml",[[lpegmatch(xmlescape,%s)]],[[local xmlescape = lpeg.patterns.xmlescape]])
-add(formatters,"tex",[[lpegmatch(texescape,%s)]],[[local texescape = lpeg.patterns.texescape]])
+-- escaping by lpeg is faster for strings without quotes, slower on a string with quotes, but
+-- faster again when other q-escapables are found (the ones we don't need to escape)
+
+add(formatters,"xml", [[lpegmatch(xmlescape,%s)]],[[local xmlescape = lpeg.patterns.xmlescape]])
+add(formatters,"tex", [[lpegmatch(texescape,%s)]],[[local texescape = lpeg.patterns.texescape]])
+add(formatters,"lua", [[lpegmatch(luaescape,%s)]],[[local luaescape = lpeg.patterns.luaescape]])
-- -- yes or no:
--
diff --git a/tex/context/base/util-tab.lua b/tex/context/base/util-tab.lua
index a47c0cb77..b7db4fa84 100644
--- a/tex/context/base/util-tab.lua
+++ b/tex/context/base/util-tab.lua
@@ -15,7 +15,7 @@ local concat, insert, remove = table.concat, table.insert, table.remove
local setmetatable, getmetatable, tonumber, tostring = setmetatable, getmetatable, tonumber, tostring
local type, next, rawset, tonumber, tostring, load, select = type, next, rawset, tonumber, tostring, load, select
local lpegmatch, P, Cs, Cc = lpeg.match, lpeg.P, lpeg.Cs, lpeg.Cc
-local serialize, sortedkeys, sortedpairs = table.serialize, table.sortedkeys, table.sortedpairs
+local sortedkeys, sortedpairs = table.sortedkeys, table.sortedpairs
local formatters = string.formatters
local splitter = lpeg.tsplitat(".")
@@ -293,100 +293,66 @@ function tables.encapsulate(core,capsule,protect)
end
end
-local function fastserialize(t,r,outer) -- no mixes
- r[#r+1] = "{"
- local n = #t
- if n > 0 then
- for i=1,n do
- local v = t[i]
- local tv = type(v)
- if tv == "string" then
- r[#r+1] = formatters["%q,"](v)
- elseif tv == "number" then
- r[#r+1] = formatters["%s,"](v)
- elseif tv == "table" then
- fastserialize(v,r)
- elseif tv == "boolean" then
- r[#r+1] = formatters["%S,"](v)
+-- we no longer have %q in keys as for this kind of tables we can
+-- assume sane keys
+
+local f_hashed_string = formatters["[%s]=%q,"]
+local f_hashed_number = formatters["[%s]=%s,"]
+local f_hashed_boolean = formatters["[%s]=%l,"]
+local f_hashed_table = formatters["[%s]="]
+
+local f_indexed_string = formatters["%q,"]
+local f_indexed_number = formatters["%s,"]
+local f_indexed_boolean = formatters["%l,"]
+
+function table.fastserialize(t,prefix) -- so prefix should contain the = | not sorted
+
+ local r = { prefix or "return" }
+ local m = 1
+
+ local function fastserialize(t,outer) -- no mixes
+ local n = #t
+ m = m + 1
+ r[m] = "{"
+ if n > 0 then
+ for i=1,n do
+ local v = t[i]
+ local tv = type(v)
+ if tv == "string" then
+ m = m + 1 r[m] = f_indexed_string(v)
+ elseif tv == "number" then
+ m = m + 1 r[m] = f_indexed_number(v)
+ elseif tv == "table" then
+ fastserialize(v)
+ elseif tv == "boolean" then
+ m = m + 1 r[m] = f_indexed_boolean(v)
+ end
end
- end
- else
- for k, v in next, t do
- local tv = type(v)
- if tv == "string" then
- r[#r+1] = formatters["[%q]=%q,"](k,v)
- elseif tv == "number" then
- r[#r+1] = formatters["[%q]=%s,"](k,v)
- elseif tv == "table" then
- r[#r+1] = formatters["[%q]="](k)
- fastserialize(v,r)
- elseif tv == "boolean" then
- r[#r+1] = formatters["[%q]=%S,"](k,v)
+ else
+ for k, v in next, t do
+ local tv = type(v)
+ if tv == "string" then
+ m = m + 1 r[m] = f_hashed_string(k,v)
+ elseif tv == "number" then
+ m = m + 1 r[m] = f_hashed_number(k,v)
+ elseif tv == "table" then
+ m = m + 1 r[m] = f_hashed_table(k)
+ fastserialize(v)
+ elseif tv == "boolean" then
+ m = m + 1 r[m] = f_hashed_boolean(k,v)
+ end
end
end
+ m = m + 1
+ if outer then
+ r[m] = "}"
+ else
+ r[m] = "},"
+ end
+ return r
end
- if outer then
- r[#r+1] = "}"
- else
- r[#r+1] = "},"
- end
- return r
-end
-
--- local f_hashed_string = formatters["[%q]=%q,"]
--- local f_hashed_number = formatters["[%q]=%s,"]
--- local f_hashed_table = formatters["[%q]="]
--- local f_hashed_true = formatters["[%q]=true,"]
--- local f_hashed_false = formatters["[%q]=false,"]
---
--- local f_indexed_string = formatters["%q,"]
--- local f_indexed_number = formatters["%s,"]
--- ----- f_indexed_true = formatters["true,"]
--- ----- f_indexed_false = formatters["false,"]
---
--- local function fastserialize(t,r,outer) -- no mixes
--- r[#r+1] = "{"
--- local n = #t
--- if n > 0 then
--- for i=1,n do
--- local v = t[i]
--- local tv = type(v)
--- if tv == "string" then
--- r[#r+1] = f_indexed_string(v)
--- elseif tv == "number" then
--- r[#r+1] = f_indexed_number(v)
--- elseif tv == "table" then
--- fastserialize(v,r)
--- elseif tv == "boolean" then
--- -- r[#r+1] = v and f_indexed_true(k) or f_indexed_false(k)
--- r[#r+1] = v and "true," or "false,"
--- end
--- end
--- else
--- for k, v in next, t do
--- local tv = type(v)
--- if tv == "string" then
--- r[#r+1] = f_hashed_string(k,v)
--- elseif tv == "number" then
--- r[#r+1] = f_hashed_number(k,v)
--- elseif tv == "table" then
--- r[#r+1] = f_hashed_table(k)
--- fastserialize(v,r)
--- elseif tv == "boolean" then
--- r[#r+1] = v and f_hashed_true(k) or f_hashed_false(k)
--- end
--- end
--- end
--- if outer then
--- r[#r+1] = "}"
--- else
--- r[#r+1] = "},"
--- end
--- return r
--- end
-function table.fastserialize(t,prefix) -- so prefix should contain the =
- return concat(fastserialize(t,{ prefix or "return" },true))
+ return concat(fastserialize(t,true))
end
function table.deserialize(str)
@@ -422,10 +388,14 @@ function table.load(filename,loader)
end
function table.save(filename,t,n,...)
- io.savedata(filename,serialize(t,n == nil and true or n,...))
+ io.savedata(filename,table.serialize(t,n == nil and true or n,...)) -- no frozen table.serialize
end
-local function slowdrop(t)
+local f_key_value = formatters["%s=%q"]
+local f_add_table = formatters[" {%t},\n"]
+local f_return_table = formatters["return {\n%t}"]
+
+local function slowdrop(t) -- maybe less memory (intermediate concat)
local r = { }
local l = { }
for i=1,#t do
@@ -433,28 +403,30 @@ local function slowdrop(t)
local j = 0
for k, v in next, ti do
j = j + 1
- l[j] = formatters["%s=%q"](k,v)
+ l[j] = f_key_value(k,v)
end
- r[i] = formatters[" {%t},\n"](l)
+ r[i] = f_add_table(l)
end
- return formatters["return {\n%st}"](r)
+ return f_return_table(r)
end
local function fastdrop(t)
local r = { "return {\n" }
+ local m = 1
for i=1,#t do
local ti = t[i]
- r[#r+1] = " {"
+ m = m + 1 r[m] = " {"
for k, v in next, ti do
- r[#r+1] = formatters["%s=%q"](k,v)
+ m = m + 1 r[m] = f_key_value(k,v)
end
- r[#r+1] = "},\n"
+ m = m + 1 r[m] = "},\n"
end
- r[#r+1] = "}"
+ m = m + 1
+ r[m] = "}"
return concat(r)
end
-function table.drop(t,slow) -- only { { a=2 }, {a=3} }
+function table.drop(t,slow) -- only { { a=2 }, {a=3} } -- for special cases
if #t == 0 then
return "return { }"
elseif slow == true then
@@ -464,6 +436,9 @@ function table.drop(t,slow) -- only { { a=2 }, {a=3} }
end
end
+-- inspect(table.drop({ { a=2 }, {a=3} }))
+-- inspect(table.drop({ { a=2 }, {a=3} },true))
+
function table.autokey(t,k)
local v = { }
t[k] = v
@@ -491,3 +466,244 @@ function table.twowaymapper(t)
return t
end
+-- The next version is somewhat faster, although in practice one will seldom
+-- serialize a lot using this one. Often the above variants are more efficient.
+-- If we would really need this a lot, we could hash q keys.
+
+-- char-def.lua : 0.53 -> 0.38
+-- husayni.tma : 0.28 -> 0.19
+
+local f_start_key_idx = formatters["%w{"]
+local f_start_key_num = formatters["%w[%s]={"]
+local f_start_key_str = formatters["%w[%q]={"]
+local f_start_key_boo = formatters["%w[%l]={"]
+local f_start_key_nop = formatters["%w{"]
+
+local f_stop = formatters["%w},"]
+
+local f_key_num_value_num = formatters["%w[%s]=%s,"]
+local f_key_str_value_num = formatters["%w[%q]=%s,"]
+local f_key_boo_value_num = formatters["%w[%l]=%s,"]
+
+local f_key_num_value_str = formatters["%w[%s]=%q,"]
+local f_key_str_value_str = formatters["%w[%q]=%q,"]
+local f_key_boo_value_str = formatters["%w[%l]=%q,"]
+
+local f_key_num_value_boo = formatters["%w[%s]=%l,"]
+local f_key_str_value_boo = formatters["%w[%q]=%l,"]
+local f_key_boo_value_boo = formatters["%w[%l]=%l,"]
+
+local f_key_num_value_not = formatters["%w[%s]={},"]
+local f_key_str_value_not = formatters["%w[%q]={},"]
+local f_key_boo_value_not = formatters["%w[%l]={},"]
+
+local f_key_num_value_seq = formatters["%w[%s]={ %, t },"]
+local f_key_str_value_seq = formatters["%w[%q]={ %, t },"]
+local f_key_boo_value_seq = formatters["%w[%l]={ %, t },"]
+
+local f_val_num = formatters["%w%s,"]
+local f_val_str = formatters["%w%q,"]
+local f_val_boo = formatters["%w%l,"]
+local f_val_not = formatters["%w{},"]
+local f_val_seq = formatters["%w{ %, t },"]
+
+local f_table_return = formatters["return {"]
+local f_table_name = formatters["%s={"]
+local f_table_direct = formatters["{"]
+local f_table_entry = formatters["[%q]={"]
+local f_table_finish = formatters["}"]
+
+----- f_string = formatters["%q"]
+
+local spaces = utilities.strings.newrepeater(" ")
+
+local serialize = table.serialize -- the extensive one, the one we started with
+
+function table.serialize(root,name,specification)
+
+ if specification then
+ return serialize(root,name,specification) -- the original one
+ end
+
+ local t -- = { }
+ local n = 1
+
+ local function simple_table(t)
+ if #t > 0 then
+ local n = 0
+ for _, v in next, t do
+ n = n + 1
+ if type(v) == "table" then
+ return nil
+ end
+ end
+ if n == #t then
+ local tt = { }
+ local nt = 0
+ for i=1,#t do
+ local v = t[i]
+ local tv = type(v)
+ nt = nt + 1
+ if tv == "number" then
+ tt[nt] = v
+ elseif tv == "string" then
+ tt[nt] = format("%q",v) -- f_string(v)
+ elseif tv == "boolean" then
+ tt[nt] = v and "true" or "false"
+ else
+ return nil
+ end
+ end
+ return tt
+ end
+ end
+ return nil
+ end
+
+ local function do_serialize(root,name,depth,level,indexed)
+ if level > 0 then
+ n = n + 1
+ if indexed then
+ t[n] = f_start_key_idx(depth)
+ else
+ local tn = type(name)
+ if tn == "number" then
+ t[n] = f_start_key_num(depth,name)
+ elseif tn == "string" then
+ t[n] = f_start_key_str(depth,name)
+ elseif tn == "boolean" then
+ t[n] = f_start_key_boo(depth,name)
+ else
+ t[n] = f_start_key_nop(depth)
+ end
+ end
+ depth = depth + 1
+ end
+ -- we could check for k (index) being number (cardinal)
+ if root and next(root) then
+ local first = nil
+ local last = 0
+ last = #root
+ for k=1,last do
+ if root[k] == nil then
+ last = k - 1
+ break
+ end
+ end
+ if last > 0 then
+ first = 1
+ end
+ local sk = sortedkeys(root) -- inline fast version?
+ for i=1,#sk do
+ local k = sk[i]
+ local v = root[k]
+ local tv = type(v)
+ local tk = type(k)
+ if first and tk == "number" and k >= first and k <= last then
+ if tv == "number" then
+ n = n + 1 t[n] = f_val_num(depth,v)
+ elseif tv == "string" then
+ n = n + 1 t[n] = f_val_str(depth,v)
+ elseif tv == "table" then
+ if not next(v) then
+ n = n + 1 t[n] = f_val_not(depth)
+ else
+ local st = simple_table(v)
+ if st then
+ n = n + 1 t[n] = f_val_seq(depth,st)
+ else
+ do_serialize(v,k,depth,level+1,true)
+ end
+ end
+ elseif tv == "boolean" then
+ n = n + 1 t[n] = f_val_boo(depth,v)
+ end
+ elseif tv == "number" then
+ if tk == "number" then
+ n = n + 1 t[n] = f_key_num_value_num(depth,k,v)
+ elseif tk == "string" then
+ n = n + 1 t[n] = f_key_str_value_num(depth,k,v)
+ elseif tk == "boolean" then
+ n = n + 1 t[n] = f_key_boo_value_num(depth,k,v)
+ end
+ elseif tv == "string" then
+ if tk == "number" then
+ n = n + 1 t[n] = f_key_num_value_str(depth,k,v)
+ elseif tk == "string" then
+ n = n + 1 t[n] = f_key_str_value_str(depth,k,v)
+ elseif tk == "boolean" then
+ n = n + 1 t[n] = f_key_boo_value_str(depth,k,v)
+ end
+ elseif tv == "table" then
+ if not next(v) then
+ if tk == "number" then
+ n = n + 1 t[n] = f_key_num_value_not(depth,k,v)
+ elseif tk == "string" then
+ n = n + 1 t[n] = f_key_str_value_not(depth,k,v)
+ elseif tk == "boolean" then
+ n = n + 1 t[n] = f_key_boo_value_not(depth,k,v)
+ end
+ else
+ local st = simple_table(v)
+ if not st then
+ do_serialize(v,k,depth,level+1)
+ elseif tk == "number" then
+ n = n + 1 t[n] = f_key_num_value_seq(depth,k,st)
+ elseif tk == "string" then
+ n = n + 1 t[n] = f_key_str_value_seq(depth,k,st)
+ elseif tk == "boolean" then
+ n = n + 1 t[n] = f_key_boo_value_seq(depth,k,st)
+ end
+ end
+ elseif tv == "boolean" then
+ if tk == "number" then
+ n = n + 1 t[n] = f_key_num_value_boo(depth,k,v)
+ elseif tk == "string" then
+ n = n + 1 t[n] = f_key_str_value_boo(depth,k,v)
+ elseif tk == "boolean" then
+ n = n + 1 t[n] = f_key_boo_value_boo(depth,k,v)
+ end
+ end
+ end
+ end
+ if level > 0 then
+ n = n + 1 t[n] = f_stop(depth-1)
+ end
+ end
+
+ local tname = type(name)
+
+ if tname == "string" then
+ if name == "return" then
+ t = { f_table_return() }
+ else
+ t = { f_table_name(name) }
+ end
+ elseif tname == "number" then
+ t = { f_table_entry(name) }
+ elseif tname == "boolean" then
+ if name then
+ t = { f_table_return() }
+ else
+ t = { f_table_direct() }
+ end
+ else
+ t = { f_table_name("t") }
+ end
+
+ if root then
+ -- The dummy access will initialize a table that has a delayed initialization
+ -- using a metatable. (maybe explicitly test for metatable)
+ if getmetatable(root) then -- todo: make this an option, maybe even per subtable
+ local dummy = root._w_h_a_t_e_v_e_r_
+ root._w_h_a_t_e_v_e_r_ = nil
+ end
+ -- Let's forget about empty tables.
+ if next(root) then
+ do_serialize(root,name,1,0)
+ end
+ end
+ n = n + 1
+ t[n] = f_table_finish()
+ return concat(t,"\n")
+end
diff --git a/tex/context/base/util-tpl.lua b/tex/context/base/util-tpl.lua
index 511076b8d..dcc4c1216 100644
--- a/tex/context/base/util-tpl.lua
+++ b/tex/context/base/util-tpl.lua
@@ -18,7 +18,7 @@ local report_template = logs.reporter("template")
local tostring = tostring
local format, sub = string.format, string.sub
-local P, C, Cs, Carg, lpegmatch = lpeg.P, lpeg.C, lpeg.Cs, lpeg.Carg, lpeg.match
+local P, C, Cs, Carg, lpegmatch, lpegpatterns = lpeg.P, lpeg.C, lpeg.Cs, lpeg.Carg, lpeg.match, lpeg.patterns
-- todo: make installable template.new
@@ -52,7 +52,10 @@ local sqlescape = lpeg.replacer {
-- { "\t", "\\t" },
}
-local sqlquotedescape = lpeg.Cs(lpeg.Cc("'") * sqlescape * lpeg.Cc("'"))
+local sqlquoted = lpeg.Cs(lpeg.Cc("'") * sqlescape * lpeg.Cc("'"))
+
+lpegpatterns.sqlescape = sqlescape
+lpegpatterns.sqlquoted = sqlquoted
-- escapeset : \0\1\2\3\4\5\6\7\8\9\10\11\12\13\14\15\16\17\18\19\20\21\22\23\24\25\26\27\28\29\30\31\"\\\127
-- test string: [[1\0\31test23"\\]] .. string.char(19) .. "23"
@@ -78,9 +81,16 @@ local sqlquotedescape = lpeg.Cs(lpeg.Cc("'") * sqlescape * lpeg.Cc("'"))
-- P(1)
-- )^0)
+-- local xmlescape = lpegpatterns.xmlescape
+-- local texescape = lpegpatterns.texescape
+-- local luaescape = lpegpatterns.luaescape
+-- local sqlquoted = lpegpatterns.sqlquoted
+-- local luaquoted = lpegpatterns.luaquoted
+
local escapers = {
lua = function(s)
- return sub(format("%q",s),2,-2)
+ -- return sub(format("%q",s),2,-2)
+ return lpegmatch(luaescape,s)
end,
sql = function(s)
return lpegmatch(sqlescape,s)
@@ -89,16 +99,14 @@ local escapers = {
local quotedescapers = {
lua = function(s)
+ -- return lpegmatch(luaquoted,s)
return format("%q",s)
end,
sql = function(s)
- return lpegmatch(sqlquotedescape,s)
+ return lpegmatch(sqlquoted,s)
end,
}
-lpeg.patterns.sqlescape = sqlescape
-lpeg.patterns.sqlquotedescape = sqlquotedescape
-
local luaescaper = escapers.lua
local quotedluaescaper = quotedescapers.lua
diff --git a/tex/context/base/x-mathml.mkiv b/tex/context/base/x-mathml.mkiv
index a4eb09467..5d70d8d3f 100644
--- a/tex/context/base/x-mathml.mkiv
+++ b/tex/context/base/x-mathml.mkiv
@@ -1,4 +1,4 @@
-%D \module
+%D \modul
%D [ file=x-mathml,
%D version=2008.05.29,
%D title=\CONTEXT\ XML Modules,
@@ -1785,25 +1785,23 @@
\stopxmlsetups
% PRESENTATION MATHML
-%
-% there are some rough edges that need to be sorted out
-
-% helpers
-
-\xmlmapvalue {mml} {normal} {\tf}
-\xmlmapvalue {mml} {double-struck} {\bf}
-\xmlmapvalue {mml} {italic} {\it}
-\xmlmapvalue {mml} {fraktur} {\bf}
-\xmlmapvalue {mml} {script} {\tf}
-\xmlmapvalue {mml} {bold} {\bf}
-\xmlmapvalue {mml} {bold-italic} {\bi}
-\xmlmapvalue {mml} {bold-fraktur} {\bf}
-\xmlmapvalue {mml} {bold-script} {\bf}
-\xmlmapvalue {mml} {sans-serif} {\ss}
-\xmlmapvalue {mml} {bold-sans-serif} {\ss\bf}
-\xmlmapvalue {mml} {sans-serif-italic} {\ss\it}
-\xmlmapvalue {mml} {sans-serif-bold-italic} {\ss\bi}
-\xmlmapvalue {mml} {monospace} {\tt}
+
+% helpers: maybe we can need a setting for the uprights
+
+\xmlmapvalue {mml} {normal} {\mathupright} % {\mathtf}
+\xmlmapvalue {mml} {double-struck} {\mathblackboard}
+\xmlmapvalue {mml} {italic} {\mathit}
+\xmlmapvalue {mml} {fraktur} {\mathfraktur}
+\xmlmapvalue {mml} {script} {\mathscript}
+\xmlmapvalue {mml} {bold} {\mb} % {\mathbf}
+\xmlmapvalue {mml} {bold-italic} {\mathbi}
+\xmlmapvalue {mml} {bold-fraktur} {\mathfraktur\mathbf}
+\xmlmapvalue {mml} {bold-script} {\mathscript\mathbf}
+\xmlmapvalue {mml} {sans-serif} {\mathss}
+\xmlmapvalue {mml} {bold-sans-serif} {\mathss\mathbf}
+\xmlmapvalue {mml} {sans-serif-italic} {\mathss\mathit}
+\xmlmapvalue {mml} {sans-serif-bold-italic} {\mathss\mathbi}
+\xmlmapvalue {mml} {monospace} {\mathtt}
% todo: displaystyle=true/false (or whatever else shows up)
@@ -1863,15 +1861,15 @@
% setups
-\startxmlsetups mml:mi % todo: mathvariant mathsize mathcolor mathbackground
- \ctxmodulemathml{mi("#1")}
+\startxmlsetups mml:mi % todo: mathsize (unlikely) mathcolor (easy) mathbackground (easy)
+ \begingroup
+ \setmmlmathstyle{#1}
+ \ctxmodulemathml{mi("#1")}
+ \endgroup
\stopxmlsetups
-\startxmlsetups mml:mn % todo: mathvariant mathsize mathcolor mathbackground
-% \begingroup
-% \mr
- \ctxmodulemathml{mn("#1")}% no \hbox, would be ok for . , but spoils rest
-% \endgroup
+\startxmlsetups mml:mn
+ \ctxmodulemathml{mn("#1")}% no \hbox, would be ok for . , but spoils rest
\stopxmlsetups
% <m:mo>-</m:mo><m:mn>2</m:mn> and <m:mn>1</m:mn><m:mo>-</m:mo><m:mn>2</m:mn>
@@ -2134,6 +2132,8 @@
% brrr no { } when limop .. todo: better in lua
% speed up with ifx and setups or just in lua
+\let\mmlnucleus\relax
+
\startxmlsetups mml:msub
\edef\mmlnucleus{\xmlraw{#1}{/mml:*[1]}}
\doifelse {\utfmathclass\mmlnucleus} {limop} {
@@ -2183,10 +2183,12 @@
\fi\fi
{\csname#1\endcsname}}
+% todo: combine topaccent/over/bottomaccent/under check
+
\startxmlsetups mml:mover
\edef\mmlovertoken{\xmlraw{#1}{/mml:*[2]}}
- \doifelseutfmathaccentfiltered\mmlovertoken{topaccent} {% not ok
- \edef\mmlovercommand{\utfmathcommandfiltered\mmlovertoken{topaccent}}
+ \doifelseutfmathabove\mmlovertoken {% not ok
+ \edef\mmlovercommand{\utfmathcommandabove\mmlovertoken}
\mmlexecuteifdefined\mmlovercommand\mathematics{\mmlfirst{#1}}
} {
\edef\mmlbasetoken{\xmlraw{#1}{/mml:*[1]}}
@@ -2212,29 +2214,27 @@
% messy: <munder><mo>(</mo><mo>&UnderBar;</mo></munder>
\startxmlsetups mml:munder
-% \mathop {
- \edef\mmlundertoken{\xmlraw{#1}{/mml:*[2]}}
- \doifelseutfmathaccentfiltered\mmlundertoken{botaccent} {
- \edef\mmlundercommand{\utfmathcommandfiltered\mmlundertoken{botaccent}}
- \mmlexecuteifdefined\mmlundercommand\mathematics{\mmlfirst{#1}}
- } {
- \edef\mmlbasetoken {\xmlraw{#1}{/mml:*[1]}}
- \edef\mmlbasecommand {\utfmathfiller\mmlbasetoken}
- \edef\mmlundercommand{\utfmathfiller\mmlundertoken}
- \vtop {
- \mathsurround\zeropoint \ialign {
- \hss$##$\hss
- \crcr
- \mmlexecuteifdefined\mmlbasecommand {\mmlfirst{#1}}
- \crcr
- \noalign{\kern3\onepoint\nointerlineskip}%
- \mmlexecuteifdefined\mmlundercommand{\mmlsecond{#1}}
- \crcr
- \noalign{\kern3\onepoint}
- }
+ \edef\mmlundertoken{\xmlraw{#1}{/mml:*[2]}}
+ \doifelseutfmathbelow\mmlundertoken {
+ \edef\mmlundercommand{\utfmathcommandbelow\mmlundertoken}
+ \mmlexecuteifdefined\mmlundercommand\mathematics{\mmlfirst{#1}}
+ } {
+ \edef\mmlbasetoken {\xmlraw{#1}{/mml:*[1]}}
+ \edef\mmlbasecommand {\utfmathfiller\mmlbasetoken}
+ \edef\mmlundercommand{\utfmathfiller\mmlundertoken}
+ \vtop {
+ \mathsurround\zeropoint \ialign {
+ \hss$##$\hss
+ \crcr
+ \mmlexecuteifdefined\mmlbasecommand {\mmlfirst{#1}}
+ \crcr
+ \noalign{\kern3\onepoint\nointerlineskip}%
+ \mmlexecuteifdefined\mmlundercommand{\mmlsecond{#1}}
+ \crcr
+ \noalign{\kern3\onepoint}
}
}
-% }
+ }
% \limits % spoils spacing
\stopxmlsetups
diff --git a/tex/context/fonts/lm.lfg b/tex/context/fonts/lm.lfg
index 792e723e8..7fad13afd 100644
--- a/tex/context/fonts/lm.lfg
+++ b/tex/context/fonts/lm.lfg
@@ -11,12 +11,13 @@ return {
tweaks = {
aftercopying = {
mathematics.tweaks.fixbadprime, -- prime is too low
+ -- mathematics.tweaks.fixoverline,
},
},
dimensions = {
-- always applied
--- default = {
--- },
+ -- default = {
+ -- },
-- driven by 'mathdimensions' feature
signs = {
-- set dimensions
diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua
index 3f3294c4a..81e3fec30 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 : luatex-fonts-merged.lua
-- parent file : luatex-fonts.lua
--- merge date : 06/07/13 12:25:27
+-- merge date : 06/10/13 12:24:08
do -- begin closure to overcome local limits and interference
@@ -1085,12 +1085,12 @@ local function simple_table(t)
else
tt[nt]=tostring(v)
end
- elseif tv=="boolean" then
- nt=nt+1
- tt[nt]=tostring(v)
elseif tv=="string" then
nt=nt+1
tt[nt]=format("%q",v)
+ elseif tv=="boolean" then
+ nt=nt+1
+ tt[nt]=v and "true" or "false"
else
tt=nil
break
@@ -1123,7 +1123,7 @@ local function do_serialize(root,name,depth,level,indexed)
handle(format("%s[%q]={",depth,name))
end
elseif tn=="boolean" then
- handle(format("%s[%s]={",depth,tostring(name)))
+ handle(format("%s[%s]={",depth,name and "true" or "false"))
else
handle(format("%s{",depth))
end
@@ -1147,21 +1147,21 @@ local function do_serialize(root,name,depth,level,indexed)
for i=1,#sk do
local k=sk[i]
local v=root[k]
- local t,tk=type(v),type(k)
+ local tv,tk=type(v),type(k)
if compact and first and tk=="number" and k>=first and k<=last then
- if t=="number" then
+ if tv=="number" then
if hexify then
handle(format("%s 0x%04X,",depth,v))
else
handle(format("%s %s,",depth,v))
end
- elseif t=="string" then
+ elseif tv=="string" then
if reduce and tonumber(v) then
handle(format("%s %s,",depth,v))
else
handle(format("%s %q,",depth,v))
end
- elseif t=="table" then
+ elseif tv=="table" then
if not next(v) then
handle(format("%s {},",depth))
elseif inline then
@@ -1174,9 +1174,9 @@ local function do_serialize(root,name,depth,level,indexed)
else
do_serialize(v,k,depth,level+1,true)
end
- elseif t=="boolean" then
- handle(format("%s %s,",depth,tostring(v)))
- elseif t=="function" then
+ elseif tv=="boolean" then
+ handle(format("%s %s,",depth,v and "true" or "false"))
+ elseif tv=="function" then
if functions then
handle(format('%s load(%q),',depth,dump(v)))
else
@@ -1189,7 +1189,7 @@ local function do_serialize(root,name,depth,level,indexed)
if false then
handle(format("%s __p__=nil,",depth))
end
- elseif t=="number" then
+ elseif tv=="number" then
if tk=="number" then
if hexify then
handle(format("%s [0x%04X]=0x%04X,",depth,k,v))
@@ -1198,9 +1198,9 @@ local function do_serialize(root,name,depth,level,indexed)
end
elseif tk=="boolean" then
if hexify then
- handle(format("%s [%s]=0x%04X,",depth,tostring(k),v))
+ handle(format("%s [%s]=0x%04X,",depth,k and "true" or "false",v))
else
- handle(format("%s [%s]=%s,",depth,tostring(k),v))
+ handle(format("%s [%s]=%s,",depth,k and "true" or "false",v))
end
elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
if hexify then
@@ -1215,7 +1215,7 @@ local function do_serialize(root,name,depth,level,indexed)
handle(format("%s [%q]=%s,",depth,k,v))
end
end
- elseif t=="string" then
+ elseif tv=="string" then
if reduce and tonumber(v) then
if tk=="number" then
if hexify then
@@ -1224,7 +1224,7 @@ local function do_serialize(root,name,depth,level,indexed)
handle(format("%s [%s]=%s,",depth,k,v))
end
elseif tk=="boolean" then
- handle(format("%s [%s]=%s,",depth,tostring(k),v))
+ handle(format("%s [%s]=%s,",depth,k and "true" or "false",v))
elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
handle(format("%s %s=%s,",depth,k,v))
else
@@ -1238,14 +1238,14 @@ local function do_serialize(root,name,depth,level,indexed)
handle(format("%s [%s]=%q,",depth,k,v))
end
elseif tk=="boolean" then
- handle(format("%s [%s]=%q,",depth,tostring(k),v))
+ handle(format("%s [%s]=%q,",depth,k and "true" or "false",v))
elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
handle(format("%s %s=%q,",depth,k,v))
else
handle(format("%s [%q]=%q,",depth,k,v))
end
end
- elseif t=="table" then
+ elseif tv=="table" then
if not next(v) then
if tk=="number" then
if hexify then
@@ -1254,7 +1254,7 @@ local function do_serialize(root,name,depth,level,indexed)
handle(format("%s [%s]={},",depth,k))
end
elseif tk=="boolean" then
- handle(format("%s [%s]={},",depth,tostring(k)))
+ handle(format("%s [%s]={},",depth,k and "true" or "false"))
elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
handle(format("%s %s={},",depth,k))
else
@@ -1270,7 +1270,7 @@ local function do_serialize(root,name,depth,level,indexed)
handle(format("%s [%s]={ %s },",depth,k,concat(st,", ")))
end
elseif tk=="boolean" then
- handle(format("%s [%s]={ %s },",depth,tostring(k),concat(st,", ")))
+ handle(format("%s [%s]={ %s },",depth,k and "true" or "false",concat(st,", ")))
elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
handle(format("%s %s={ %s },",depth,k,concat(st,", ")))
else
@@ -1282,21 +1282,21 @@ local function do_serialize(root,name,depth,level,indexed)
else
do_serialize(v,k,depth,level+1)
end
- elseif t=="boolean" then
+ elseif tv=="boolean" then
if tk=="number" then
if hexify then
- handle(format("%s [0x%04X]=%s,",depth,k,tostring(v)))
+ handle(format("%s [0x%04X]=%s,",depth,k,v and "true" or "false"))
else
- handle(format("%s [%s]=%s,",depth,k,tostring(v)))
+ handle(format("%s [%s]=%s,",depth,k,v and "true" or "false"))
end
elseif tk=="boolean" then
- handle(format("%s [%s]=%s,",depth,tostring(k),tostring(v)))
+ handle(format("%s [%s]=%s,",depth,tostring(k),v and "true" or "false"))
elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
- handle(format("%s %s=%s,",depth,k,tostring(v)))
+ handle(format("%s %s=%s,",depth,k,v and "true" or "false"))
else
- handle(format("%s [%q]=%s,",depth,k,tostring(v)))
+ handle(format("%s [%q]=%s,",depth,k,v and "true" or "false"))
end
- elseif t=="function" then
+ elseif tv=="function" then
if functions then
local f=getinfo(v).what=="C" and dump(dummy) or dump(v)
if tk=="number" then
@@ -1306,7 +1306,7 @@ local function do_serialize(root,name,depth,level,indexed)
handle(format("%s [%s]=load(%q),",depth,k,f))
end
elseif tk=="boolean" then
- handle(format("%s [%s]=load(%q),",depth,tostring(k),f))
+ handle(format("%s [%s]=load(%q),",depth,k and "true" or "false",f))
elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
handle(format("%s %s=load(%q),",depth,k,f))
else
@@ -1321,7 +1321,7 @@ local function do_serialize(root,name,depth,level,indexed)
handle(format("%s [%s]=%q,",depth,k,tostring(v)))
end
elseif tk=="boolean" then
- handle(format("%s [%s]=%q,",depth,tostring(k),tostring(v)))
+ handle(format("%s [%s]=%q,",depth,k and "true" or "false",tostring(v)))
elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
handle(format("%s %s=%q,",depth,k,tostring(v)))
else
@@ -2926,10 +2926,13 @@ local function add(t,name,template,preamble)
end
end
strings.formatters.add=add
-lpeg.patterns.xmlescape=Cs((P("<")/"&lt;"+P(">")/"&gt;"+P("&")/"&amp;"+P('"')/"&quot;"+P(1))^0)
-lpeg.patterns.texescape=Cs((C(S("#$%\\{}"))/"\\%1"+P(1))^0)
+patterns.xmlescape=Cs((P("<")/"&lt;"+P(">")/"&gt;"+P("&")/"&amp;"+P('"')/"&quot;"+P(1))^0)
+patterns.texescape=Cs((C(S("#$%\\{}"))/"\\%1"+P(1))^0)
+patterns.luaescape=Cs(((1-S('"\n'))^1+P('"')/'\\"'+P('\n')/'\\n"')^0)
+patterns.luaquoted=Cs(Cc('"')*((1-S('"\n'))^1+P('"')/'\\"'+P('\n')/'\\n"')^0*Cc('"'))
add(formatters,"xml",[[lpegmatch(xmlescape,%s)]],[[local xmlescape = lpeg.patterns.xmlescape]])
add(formatters,"tex",[[lpegmatch(texescape,%s)]],[[local texescape = lpeg.patterns.texescape]])
+add(formatters,"lua",[[lpegmatch(luaescape,%s)]],[[local luaescape = lpeg.patterns.luaescape]])
end -- closure
@@ -10100,8 +10103,6 @@ local function featuresprocessor(head,font,attr)
else
start=start.next
end
- elseif id==math_code then
- start=end_of_math(start).next
else
start=start.next
end