summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/context/base/math-ini.lua
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/tex/context/base/math-ini.lua')
-rw-r--r--Master/texmf-dist/tex/context/base/math-ini.lua404
1 files changed, 232 insertions, 172 deletions
diff --git a/Master/texmf-dist/tex/context/base/math-ini.lua b/Master/texmf-dist/tex/context/base/math-ini.lua
index 54452282bb0..530e685685e 100644
--- a/Master/texmf-dist/tex/context/base/math-ini.lua
+++ b/Master/texmf-dist/tex/context/base/math-ini.lua
@@ -1,4 +1,4 @@
-if not modules then modules = { } end modules ['math-ext'] = {
+if not modules then modules = { } end modules ['math-ini'] = {
version = 1.001,
comment = "companion to math-ini.mkiv",
author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
@@ -11,7 +11,8 @@ if not modules then modules = { } end modules ['math-ext'] = {
--
-- isn't characters.data loaded already ... shortcut it here
-local format, utfchar, utfbyte = string.format, utf.char, utf.byte
+local formatters = string.formatters
+local utfchar, utfbyte = utf.char, utf.byte
local setmathcode, setdelcode = tex.setmathcode, tex.setdelcode
local texattribute = tex.attribute
local floor = math.floor
@@ -33,34 +34,66 @@ local mathematics = mathematics
mathematics.extrabase = 0xFE000 -- here we push some virtuals
mathematics.privatebase = 0xFF000 -- here we push the ex
+local chardata = characters.data
+
local families = allocate {
mr = 0,
mb = 1,
}
local classes = allocate {
- ord = 0, -- mathordcomm mathord
- op = 1, -- mathopcomm mathop
- bin = 2, -- mathbincomm mathbin
- rel = 3, -- mathrelcomm mathrel
- open = 4, -- mathopencomm mathopen
- close = 5, -- mathclosecomm mathclose
- punct = 6, -- mathpunctcomm mathpunct
- alpha = 7, -- mathalphacomm firstofoneargument
- accent = 8, -- class 0
- radical = 9,
- xaccent = 10, -- class 3
- topaccent = 11, -- class 0
- botaccent = 12, -- class 0
- under = 13,
- over = 14,
- delimiter = 15,
- inner = 0, -- mathinnercomm mathinner
- nothing = 0, -- mathnothingcomm firstofoneargument
- choice = 0, -- mathchoicecomm @@mathchoicecomm
- box = 0, -- mathboxcomm @@mathboxcomm
- limop = 1, -- mathlimopcomm @@mathlimopcomm
- nolop = 1, -- mathnolopcomm @@mathnolopcomm
+ ord = 0, -- mathordcomm mathord
+ op = 1, -- mathopcomm mathop
+ bin = 2, -- mathbincomm mathbin
+ rel = 3, -- mathrelcomm mathrel
+ open = 4, -- mathopencomm mathopen
+ middle = 4,
+ close = 5, -- mathclosecomm mathclose
+ punct = 6, -- mathpunctcomm mathpunct
+ alpha = 7, -- mathalphacomm firstofoneargument
+ accent = 8, -- class 0
+ radical = 9,
+ xaccent = 10, -- class 3
+ topaccent = 11, -- class 0
+ botaccent = 12, -- class 0
+ under = 13,
+ over = 14,
+ delimiter = 15,
+ inner = 0, -- mathinnercomm mathinner
+ nothing = 0, -- mathnothingcomm firstofoneargument
+ choice = 0, -- mathchoicecomm @@mathchoicecomm
+ box = 0, -- mathboxcomm @@mathboxcomm
+ limop = 1, -- mathlimopcomm @@mathlimopcomm
+ nolop = 1, -- mathnolopcomm @@mathnolopcomm
+ --
+ ordinary = 0, -- ord
+ alphabetic = 7, -- alpha
+ unknown = 0, -- nothing
+ default = 0, -- nothing
+ punctuation = 6, -- punct
+ normal = 0, -- nothing
+ opening = 4, -- open
+ closing = 5, -- close
+ binary = 2, -- bin
+ relation = 3, -- rel
+ fence = 0, -- unknown
+ diacritic = 8, -- accent
+ large = 1, -- op
+ variable = 7, -- alphabetic
+ number = 7, -- alphabetic
+}
+
+local open_class = 4
+local middle_class = 4
+local close_class = 5
+
+local accents = allocate {
+ accent = true, -- some can be both
+ topaccent = true, [11] = true,
+ botaccent = true, [12] = true,
+ under = true, [13] = true,
+ over = true, [14] = true,
+ unknown = false,
}
local codes = allocate {
@@ -74,165 +107,118 @@ local codes = allocate {
variable = 7, [7] = "variable",
}
-mathematics.classes = classes
-mathematics.codes = codes
-mathematics.families = families
-
-classes.alphabetic = classes.alpha
-classes.unknown = classes.nothing
-classes.default = classes.nothing
-classes.punctuation = classes.punct
-classes.normal = classes.nothing
-classes.opening = classes.open
-classes.closing = classes.close
-classes.binary = classes.bin
-classes.relation = classes.rel
-classes.fence = classes.unknown
-classes.diacritic = classes.accent
-classes.large = classes.op
-classes.variable = classes.alphabetic
-classes.number = classes.alphabetic
+local extensibles = allocate {
+ unknown = 0,
+ l = 1, left = 1,
+ r = 2, right = 2,
+ h = 3, horizontal = 3,-- lr or rl
+ u = 5, up = 4,
+ d = 5, down = 5,
+ v = 6, vertical = 6,-- ud or du
+ m = 7, mixed = 7,
+}
+
+table.setmetatableindex(extensibles,function(t,k) t[k] = 0 return 0 end)
+
+mathematics.extensibles = extensibles
+mathematics.classes = classes
+mathematics.codes = codes
+-----------.accents = codes
+mathematics.families = families
-- there will be proper functions soon (and we will move this code in-line)
-- no need for " in class and family (saves space)
-local function delcode(target,family,slot)
- return format('\\Udelcode%s="%X "%X ',target,family,slot)
-end
local function mathchar(class,family,slot)
- return format('\\Umathchar "%X "%X "%X ',class,family,slot)
+ return formatters['\\Umathchar "%X "%X "%X '](class,family,slot)
end
+
local function mathaccent(class,family,slot)
- return format('\\Umathaccent "%X "%X "%X ',0,family,slot) -- no class
+ return formatters['\\Umathaccent "%X "%X "%X '](0,family,slot) -- no class
end
+
local function delimiter(class,family,slot)
- return format('\\Udelimiter "%X "%X "%X ',class,family,slot)
+ return formatters['\\Udelimiter "%X "%X "%X '](class,family,slot)
end
+
local function radical(family,slot)
- return format('\\Uradical "%X "%X ',family,slot)
+ return formatters['\\Uradical "%X "%X '](family,slot)
end
+
local function mathchardef(name,class,family,slot)
- return format('\\Umathchardef\\%s "%X "%X "%X ',name,class,family,slot)
+ return formatters['\\Umathchardef\\%s "%X "%X "%X '](name,class,family,slot)
end
+
local function mathcode(target,class,family,slot)
- return format('\\Umathcode%s="%X "%X "%X ',target,class,family,slot)
+ return formatters['\\Umathcode%s="%X "%X "%X '](target,class,family,slot)
end
+
local function mathtopaccent(class,family,slot)
- return format('\\Umathaccent "%X "%X "%X ',0,family,slot) -- no class
+ return formatters['\\Umathaccent "%X "%X "%X '](0,family,slot) -- no class
end
+
local function mathbotaccent(class,family,slot)
- return format('\\Umathaccent bottom "%X "%X "%X ',0,family,slot) -- no class
+ return formatters['\\Umathaccent bottom "%X "%X "%X '](0,family,slot) -- no class
end
+
local function mathtopdelimiter(class,family,slot)
- return format('\\Udelimiterover "%X "%X ',family,slot) -- no class
+ return formatters['\\Udelimiterover "%X "%X '](family,slot) -- no class
end
+
local function mathbotdelimiter(class,family,slot)
- return format('\\Udelimiterunder "%X "%X ',family,slot) -- no class
+ return formatters['\\Udelimiterunder "%X "%X '](family,slot) -- no class
end
local escapes = characters.filters.utf.private.escapes
-local setmathcharacter, setmathsynonym, setmathsymbol -- once updated we will inline them
-
--- beware ... we only set the math character once ... which is why we
--- have the 'done' checking below
-
-if setmathcode then
+-- not that many so no need to reuse tables
- setmathcharacter = function(class,family,slot,unicode)
- if class <= 7 then
- setmathcode(slot,{class,family,unicode or slot})
- end
- end
-
- setmathsynonym = function(class,family,slot,unicode,setcode)
- if setcode and class <= 7 then
- setmathcode(slot,{class,family,unicode})
- end
- if class == classes.open or class == classes.close then
- setdelcode(slot,{family,unicode,0,0})
- end
- end
-
- setmathsymbol = function(name,class,family,slot) -- hex is nicer for tracing
- if class == classes.accent then
- contextsprint(format([[\unexpanded\gdef\%s{\Umathaccent 0 "%X "%X }]],name,family,slot))
- elseif class == classes.topaccent then
- contextsprint(format([[\unexpanded\gdef\%s{\Umathaccent 0 "%X "%X }]],name,family,slot))
- elseif class == classes.botaccent then
- contextsprint(format([[\unexpanded\gdef\%s{\Umathbotaccent 0 "%X "%X }]],name,family,slot))
- elseif class == classes.over then
- contextsprint(format([[\unexpanded\gdef\%s{\Udelimiterover "%X "%X }]],name,family,slot))
- elseif class == classes.under then
- contextsprint(format([[\unexpanded\gdef\%s{\Udelimiterunder "%X "%X }]],name,family,slot))
- elseif class == classes.open or class == classes.close then
- setdelcode(slot,{family,slot,0,0})
- contextsprint(format([[\unexpanded\gdef\%s{\Udelimiter "%X "%X "%X }]],name,class,family,slot))
- elseif class == classes.delimiter then
- setdelcode(slot,{family,slot,0,0})
- contextsprint(format([[\unexpanded\gdef\%s{\Udelimiter 0 "%X "%X }]],name,family,slot))
- elseif class == classes.radical then
- contextsprint(format([[\unexpanded\gdef\%s{\Uradical "%X "%X }]],name,family,slot))
- else
- -- beware, open/close and other specials should not end up here
--- contextsprint(format([[\unexpanded\gdef\%s{\Umathchar "%X "%X "%X }]],name,class,family,slot))
- contextsprint(format([[\Umathchardef\%s "%X "%X "%X ]],name,class,family,slot))
- end
+local setmathcharacter = function(class,family,slot,unicode,mset,dset)
+ if mset and codes[class] then -- regular codes < 7
+ setmathcode("global",slot,{class,family,unicode})
+ mset = false
end
-
-
-else
-
- setmathcharacter = function(class,family,slot,unicode)
- if class <= 7 then
- contextsprint(mathcode(slot,class,family,unicode or slot))
- end
- end
-
- setmathsynonym = function(class,family,slot,unicode,setcode)
- if setcode and class <= 7 then
- contextsprint(mathcode(slot,class,family,unicode))
- end
- if class == classes.open or class == classes.close then
- contextsprint(delcode(slot,family,unicode))
- end
+ if dset and class == open_class or class == close_class or class == middle_class then
+ setdelcode("global",slot,{family,unicode,0,0})
+ dset = false
end
+ return mset, dset
+end
- setmathsymbol = function(name,class,family,slot)
- if class == classes.accent then
- contextsprint(format([[\unexpanded\xdef\%s{%s}]],name,mathaccent(class,family,slot)))
- elseif class == classes.topaccent then
- contextsprint(format([[\unexpanded\xdef\%s{%s}]],name,mathtopaccent(class,family,slot)))
- elseif class == classes.botaccent then
- contextsprint(format([[\unexpanded\xdef\%s{%s}]],name,mathbotaccent(class,family,slot)))
- elseif class == classes.over then
- contextsprint(format([[\unexpanded\xdef\%s{%s}]],name,mathtopdelimiter(class,family,slot)))
- elseif class == classes.under then
- contextsprint(format([[\unexpanded\xdef\%s{%s}]],name,mathbotdelimiter(class,family,slot)))
- elseif class == classes.open or class == classes.close then
- contextsprint(delcode(slot,family,slot))
- contextsprint(format([[\unexpanded\xdef\%s{%s}]],name,delimiter(class,family,slot)))
- elseif class == classes.delimiter then
- contextsprint(delcode(slot,family,slot))
- contextsprint(format([[\unexpanded\xdef\%s{%s}]],name,delimiter(0,family,slot)))
- elseif class == classes.radical then
- contextsprint(format([[\unexpanded\xdef\%s{%s}]],name,radical(family,slot)))
- else
- -- beware, open/close and other specials should not end up here
- contextsprint(format([[\unexpanded\xdef\%s{%s}]],name,mathchar(class,family,slot)))
- end
+local setmathsymbol = function(name,class,family,slot) -- hex is nicer for tracing
+ if class == classes.accent then
+ contextsprint(formatters[ [[\ugdef\%s{\Umathaccent 0 "%X "%X }]] ](name,family,slot))
+ elseif class == classes.topaccent then
+ contextsprint(formatters[ [[\ugdef\%s{\Umathaccent 0 "%X "%X }]] ](name,family,slot))
+ elseif class == classes.botaccent then
+ contextsprint(formatters[ [[\ugdef\%s{\Umathbotaccent 0 "%X "%X }]] ](name,family,slot))
+ elseif class == classes.over then
+ contextsprint(formatters[ [[\ugdef\%s{\Udelimiterover "%X "%X }]] ](name,family,slot))
+ elseif class == classes.under then
+ contextsprint(formatters[ [[\ugdef\%s{\Udelimiterunder "%X "%X }]] ](name,family,slot))
+ elseif class == open_class or class == close_class or class == middle_class then
+ setdelcode(slot,{family,slot,0,0})
+ contextsprint(formatters[ [[\ugdef\%s{\Udelimiter "%X "%X "%X }]] ](name,class,family,slot))
+ elseif class == classes.delimiter then
+ setdelcode(slot,{family,slot,0,0})
+ contextsprint(formatters[ [[\ugdef\%s{\Udelimiter 0 "%X "%X }]] ](name,family,slot))
+ elseif class == classes.radical then
+ contextsprint(formatters[ [[\ugdef\%s{\Uradical "%X "%X }]] ](name,family,slot))
+ else
+ -- beware, open/close and other specials should not end up here
+ -- contextsprint(formatters[ [[\ugdef\%s{\Umathchar "%X "%X "%X }]],name,class,family,slot))
+ contextsprint(formatters[ [[\Umathchardef\%s "%X "%X "%X ]] ](name,class,family,slot))
end
-
end
local function report(class,family,unicode,name)
local nametype = type(name)
if nametype == "string" then
- report_math("%s:%s %s U+%05X (%s) => %s",classname,class,family,unicode,utfchar(unicode),name)
+ report_math("class name %a, class %a, family %a, char %C, name %a",classname,class,family,unicode,name)
elseif nametype == "number" then
- report_math("%s:%s %s U+%05X (%s) => U+%05X",classname,class,family,unicode,utfchar(unicode),name)
+ report_math("class name %a, class %a, family %a, char %C, number %U",classname,class,family,unicode,name)
else
- report_math("%s:%s %s U+%05X (%s)", classname,class,family,unicode,utfchar(unicode))
+ report_math("class name %a, class %a, family %a, char %C", classname,class,family,unicode)
end
end
@@ -244,7 +230,7 @@ function mathematics.define(family)
local data = characters.data
for unicode, character in next, data do
local symbol = character.mathsymbol
- local setcode = true
+ local mset, dset = true, true
if symbol then
local other = data[symbol]
local class = other.mathclass
@@ -253,8 +239,7 @@ function mathematics.define(family)
if trace_defining then
report(class,family,unicode,symbol)
end
- setmathsynonym(class,family,unicode,symbol,setcode)
- setcode = false
+ mset, dset = setmathcharacter(class,family,unicode,symbol,mset,dset)
end
local spec = other.mathspec
if spec then
@@ -262,8 +247,7 @@ function mathematics.define(family)
local class = m.class
if class then
class = classes[class] or class -- no real checks needed
- setmathsynonym(class,family,unicode,symbol,setcode)
- setcode = false
+ mset, dset = setmathcharacter(class,family,unicode,symbol,mset,dset)
end
end
end
@@ -288,16 +272,11 @@ function mathematics.define(family)
setmathsymbol(name,class,family,unicode)
else
name = class == classes.variable or class == classes.number and character.adobename
- if name then
- if trace_defining then
- report(class,family,unicode,name)
- end
+ if name and trace_defining then
+ report(class,family,unicode,name)
end
end
- if setcode then
- setmathcharacter(class,family,unicode,unicode)
- setcode = false
- end
+ mset, dset = setmathcharacter(class,family,unicode,m.unicode or unicode,mset,dset) -- see solidus
end
end
end
@@ -308,7 +287,7 @@ function mathematics.define(family)
if trace_defining then
report(class,family,unicode,name)
end
- setmathcharacter(class,family,unicode)
+ mset, dset = setmathcharacter(class,family,unicode,mset,dset)
else
name = name or character.contextname
if name then
@@ -321,7 +300,7 @@ function mathematics.define(family)
report(class,family,unicode,character.adobename)
end
end
- setmathcharacter(class,family,unicode,unicode)
+ mset, dset = setmathcharacter(class,family,unicode,unicode,mset,dset)
end
end
end
@@ -329,24 +308,102 @@ end
-- needed for mathml analysis
+-- we could cache
+
local function utfmathclass(chr, default)
- local cd = characters.data[utfbyte(chr)]
- return (cd and cd.mathclass) or default or "unknown"
+ local cd = chardata[utfbyte(chr)]
+ return cd and cd.mathclass or default or "unknown"
+end
+
+local function utfmathaccent(chr,default,asked)
+ local cd = chardata[utfbyte(chr)]
+ if not cd then
+ return default or false
+ end
+ if asked then
+ local mc = cd.mathclass
+ if mc and mc == asked then
+ return true
+ end
+ local ms = cd.mathspec
+ if ms then
+ for i=1,#ms do
+ local msi = ms[i]
+ local mc = msi.class
+ if mc and mc == asked then
+ return true
+ end
+ end
+ end
+ else
+ local mc = cd.mathclass
+ if mc then
+ return accents[mc] or default or false
+ end
+ local ms = cd.mathspec
+ if ms then
+ for i=1,#ms do
+ local msi = ms[i]
+ local mc = msi.class
+ if mc then
+ return accents[mc] or default or false
+ end
+ end
+ end
+ end
+ return default or false
end
local function utfmathstretch(chr, default) -- "h", "v", "b", ""
- local cd = characters.data[utfbyte(chr)]
- return (cd and cd.mathstretch) or default or ""
+ local cd = chardata[utfbyte(chr)]
+ return cd and cd.mathstretch or default or ""
end
-local function utfmathcommand(chr, default)
- local cd = characters.data[utfbyte(chr)]
- local cmd = cd and cd.mathname
- return cmd or default or ""
+local function utfmathcommand(chr,default,asked)
+-- local cd = chardata[utfbyte(chr)]
+-- local cmd = cd and cd.mathname
+-- return cmd or default or ""
+ local cd = chardata[utfbyte(chr)]
+ if not cd then
+ return default or ""
+ end
+ if asked then
+ local mn = cd.mathname
+ local mc = cd.mathclass
+ if mn and mc and mc == asked then
+ return mn
+ end
+ local ms = cd.mathspec
+ if ms then
+ for i=1,#ms do
+ local msi = ms[i]
+ local mn = msi.name
+ if mn and msi.class == asked then
+ return mn
+ end
+ end
+ end
+ else
+ local mn = cd.mathname
+ if mn then
+ return mn
+ end
+ local ms = cd.mathspec
+ if ms then
+ for i=1,#ms do
+ local msi = ms[i]
+ local mn = msi.name
+ if mn then
+ return mn
+ end
+ end
+ end
+ end
+ return default or ""
end
local function utfmathfiller(chr, default)
- local cd = characters.data[utfbyte(chr)]
+ local cd = chardata[utfbyte(chr)]
local cmd = cd and (cd.mathfiller or cd.mathname)
return cmd or default or ""
end
@@ -358,11 +415,14 @@ mathematics.utfmathfiller = utfmathfiller
-- interfaced
-function commands.utfmathclass (chr) context(utfmathclass (chr)) end
-function commands.utfmathstretch(chr) context(utfmathstretch(chr)) end
-function commands.utfmathcommand(chr) context(utfmathcommand(chr)) end
-function commands.utfmathfiller (chr) context(utfmathfiller (chr)) end
+function commands.utfmathclass (...) context(utfmathclass (...)) end
+function commands.utfmathstretch(...) context(utfmathstretch(...)) end
+function commands.utfmathcommand(...) context(utfmathcommand(...)) end
+function commands.utfmathfiller (...) context(utfmathfiller (...)) end
+function commands.doifelseutfmathaccent(chr,asked)
+ commands.doifelse(utfmathaccent(chr,nil,asked))
+end
-- helpers