summaryrefslogtreecommitdiff
path: root/tex/context/base/mkxl/math-ini.lmt
diff options
context:
space:
mode:
Diffstat (limited to 'tex/context/base/mkxl/math-ini.lmt')
-rw-r--r--tex/context/base/mkxl/math-ini.lmt446
1 files changed, 276 insertions, 170 deletions
diff --git a/tex/context/base/mkxl/math-ini.lmt b/tex/context/base/mkxl/math-ini.lmt
index 4ac76fa62..f41170a97 100644
--- a/tex/context/base/mkxl/math-ini.lmt
+++ b/tex/context/base/mkxl/math-ini.lmt
@@ -31,6 +31,8 @@ local ctx_doifelsesomething = commands.doifelsesomething
local trace_defining = false trackers.register("math.defining", function(v) trace_defining = v end)
+trace_defining = true
+
local report_math = logs.reporter("mathematics","initializing")
mathematics = mathematics or { }
@@ -47,86 +49,159 @@ local texsetattribute = tex.setattribute
local setmathcode = tex.setmathcode
local setdelcode = tex.setdelcode
-local families = allocate {
- mr = 0,
- mb = 1,
-}
+-- These are different from mkiv with luatex.
---- to be checked .. a few defaults in char-def that should be alpha
-
-local classes = allocate {
- 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
- root = 16, -- a private one
+local classes = allocate { }
+local classnames = allocate { }
+local maxengineclass = 63
+local lastengineclass = 0
+local lastprivateclass = maxengineclass
+
+for k, v in next, nodes.noadcodes do
+ if type(k) == "string"then
+ classes[k] = v
+ local n = classnames[v]
+ if not n or #k < #n then
+ classnames[v] = k
+ end
+ elseif k > lastengineclass then
+ lastengineclass = k
+ end
+end
+
+local ordinary_class = classes.ordinary
+local operator_class = classes.operator
+local binary_class = classes.binary
+local relation_class = classes.relation
+local open_class = classes.open
+local close_class = classes.close
+local punctuation_class = classes.punctuation
+local middle_class = classes.middle
+local accent_class = classes.accent
+local radical_class = classes.radical
+local fraction_class = classes.fraction
+local under_class = classes.under
+local over_class = classes.over
+local fenced_class = classes.fenced
+local ghost_class = classes.ghost
+
+classes.ord = ordinary_class
+classes.op = operator_class
+classes.bin = binary_class
+classes.rel = relation_class
+classes.opening = open_class -- will go
+classes.closing = close_class -- will go
+classes.punct = punctuation_class
+classes.frac = fraction_class
+classes.rad = radical_class
+classes.fen = fenced_class
+classes.gst = ghost_class
+
+classes.limop = operator_class
+classes.limoperator = operator_class
+classes.nolop = operator_class
+classes.nolimoperator = operator_class
+classes.large = operator_class
+classes.largeoperator = operator_class
+
+-- special in the engine : variable active inner vcenter
+
+local function registerengineclass(name,short)
+ local class = classes[name]
+ if not class then
+ if lastengineclass < maxengineclass then
+ lastengineclass = lastengineclass + 1
+ class = lastengineclass
+ classnames[class] = short or name
+ else
+ class = ordinary_class
+ end
+ classes[name] = class
+ end
+ return class
+end
+
+local explicit_class = registerengineclass("explicit","expl")
+local imaginary_class = registerengineclass("imaginary","im")
+local diferential_class = registerengineclass("differential","dif")
+local exponential_class = registerengineclass("exponential","exp")
+local function_class = registerengineclass("function","fnc")
+local digit_class = registerengineclass("digit","dig")
+local division_class = registerengineclass("division","div")
+local factorial_class = registerengineclass("factorial","fac")
+
+classes["begin"] = 62 classnames[62] = "begin"
+classes["end"] = 63 classnames[63] = "end"
+
+local function registerprivateclass(name)
+ local class = classes[name]
+ if not class then
+ lastprivateclass = lastprivateclass + 1
+ class = lastprivateclass
+ classes[name] = class
+ -- also setup
+ end
+ return class
+end
+
+local function toengineclass(class)
+ if type(class) == "string" then
+ return classes[class] or ordinary_class
+ elseif class > lastengineclass then
+ return ordinary_class
+ else
+ return class
+ end
+end
+
+implement {
+ name = "registerengineclass",
+ public = true,
+ protected = true,
+ arguments = { "optional", "optional" },
+ actions = registerengineclass,
}
-local open_class = 4
-local middle_class = 4
-local close_class = 5
-local accent_class = 8
-local radical_class = 9
-local topaccent_class = 11
-local botaccent_class = 12
-local under_class = 13
-local over_class = 14
-local delimiter_class = 15
-local root_class = 16
+local topaccent_class = registerprivateclass("topaccent")
+local botaccent_class = registerprivateclass("botaccent")
+local delimiter_class = registerprivateclass("delimiter")
+local root_class = registerprivateclass("root")
+local prime_class = registerprivateclass("prime")
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,
+ topaccent = true, [topaccent_class] = true,
+ botaccent = true, [botaccent_class] = true,
+ under = true, [under_class] = true,
+ over = true, [over_class] = true,
unknown = false,
}
+local integer_value = tokens.values.integer
+
+implement {
+ name = "mathclassvalue",
+ -- usage = "value",
+ public = true,
+ arguments = "string",
+ actions = function(name)
+ -- return integer_value, classes[name] or ordinary_class
+ context(tostring(classes[name] or ordinary_class))
+ end
+}
+
+-- used in math-tag: so there we need to make things ord etc to fit within
+-- mathml
+
local codes = allocate {
- ordinary = 0, [0] = "ordinary",
- largeoperator = 1, "largeoperator",
- binaryoperator = 2, "binaryoperator",
- relation = 3, "relation",
- openingsymbol = 4, "openingsymbol",
- closingsymbol = 5, "closingsymbol",
- punctuation = 6, "punctuation",
- variable = 7, "variable",
+ ordinary = ordinary_class, [ordinary_class] = "ordinary",
+ largeoperator = operator_class, [operator_class] = "largeoperator",
+ binaryoperator = binary_class, [binary_class] = "binaryoperator",
+ relation = relation_class, [relation_class] = "relation",
+ openingsymbol = open_class, [open_class] = "openingsymbol",
+ closingsymbol = close_class, [close_class] = "closingsymbol",
+ punctuation = punctuation_class, [punctuation_class] = "punctuation",
+ middlesymbol = middle_class, [middle_class] = "middlesymbol",
}
local extensibles = allocate {
@@ -169,61 +244,69 @@ function mathematics.virtualize(unicode,virtual)
end
end
-mathematics.extensibles = extensibles
-mathematics.classes = classes
-mathematics.codes = codes
------------.accents = codes
-mathematics.families = families
-mathematics.virtualized = virtualized
+mathematics.extensibles = extensibles
+mathematics.classes = classes
+mathematics.toengineclass = toengineclass
+mathematics.classnames = classnames
+mathematics.codes = codes
+-----------.accents = codes
+mathematics.virtualized = virtualized
do
- -- not that many so no need to reuse tables
-
local setmathcharacter = function(class,family,slot,unicode,mset,dset)
- if mset and codes[class] then -- regular codes < 7
+ if mset and class ~= ordinary_class then
setmathcode("global",slot,class,family,unicode)
mset = false
end
- if dset and class == open_class or class == close_class or class == middle_class then
+ if dset and (class == open_class or class == close_class or class == middle_class or class == division_class) then
setdelcode("global",slot,family,unicode,0,0)
dset = false
end
return mset, dset
end
- -- todo: make nice setters for this in lua
+ local function report(class,engine,family,unicode,name)
+ local nametype = type(name)
+ if nametype == "string" then
+ report_math("class %a, engine %a, family %a, char %C, name %a",class,engine,family,unicode,name)
+ elseif nametype == "number" then
+ report_math("class %a, engine %a, family %a, char %C, number %U",class,engine,family,unicode,name)
+ else
+ report_math("class %a, engine %a, family %a, char %C",class,engine,family,unicode)
+ end
+ end
- local f_accent = formatters[ [[\defUmathtopaccent \%s{%X}{%X}{%X}]] ]
- local f_topaccent = formatters[ [[\defUmathtopaccent \%s{%X}{%X}{%X}]] ]
- local f_botaccent = formatters[ [[\defUmathbotaccent \%s{%X}{%X}{%X}]] ]
- local f_over = formatters[ [[\defUdelimiterover \%s{%X}{%X}{%X}]] ]
- local f_under = formatters[ [[\defUdelimiterunder\%s{%X}{%X}{%X}]] ]
- local f_fence = formatters[ [[\defUdelimiter \%s{%X}{%X}{%X}]] ]
- local f_delimiter = formatters[ [[\defUdelimiter \%s{%X}{%X}{%X}]] ]
- local f_radical = formatters[ [[\defUradical \%s{%X}{%X}]] ]
- local f_root = formatters[ [[\defUroot \%s{%X}{%X}]] ]
- local f_char = formatters[ [[\defUmathchar \%s{%X}{%X}{%X}]] ]
+ local f_accent = formatters[ [[\defUmathtopaccent \%s{%X}{%X}{%X}]] ]
+ local f_fixedtopaccent = formatters[ [[\defUmathfixedtopaccent \%s{%X}{%X}{%X}]] ]
+ local f_fixedbotaccent = formatters[ [[\defUmathfixedbotaccent \%s{%X}{%X}{%X}]] ]
+ local f_topaccent = formatters[ [[\defUmathtopaccent \%s{%X}{%X}{%X}]] ]
+ local f_botaccent = formatters[ [[\defUmathbotaccent \%s{%X}{%X}{%X}]] ]
+ local f_over = formatters[ [[\defUdelimiterover \%s{%X}{%X}{%X}]] ]
+ local f_under = formatters[ [[\defUdelimiterunder\%s{%X}{%X}{%X}]] ]
+ local f_fence = formatters[ [[\defUdelimiter \%s{%X}{%X}{%X}]] ]
+ local f_delimiter = formatters[ [[\defUdelimiter \%s{%X}{%X}{%X}]] ]
+ local f_radical = formatters[ [[\defUradical \%s{%X}{%X}]] ]
+ local f_root = formatters[ [[\defUroot \%s{%X}{%X}]] ]
+ local f_char = formatters[ [[\defUmathchar \%s{%X}{%X}{%X}]] ]
local texmathchardef = tex.mathchardef
- local setmathsymbol = function(name,class,family,slot) -- hex is nicer for tracing
+ local setmathsymbol = function(name,class,engine,family,slot,stretch) -- hex is nicer for tracing
if class == accent_class then
ctx_sprint(f_topaccent(name,0,family,slot))
elseif class == topaccent_class then
- ctx_sprint(f_topaccent(name,0,family,slot))
+ ctx_sprint((stretch and f_topaccent or f_fixedtopaccent)(name,0,family,slot))
elseif class == botaccent_class then
- ctx_sprint(f_botaccent(name,0,family,slot))
+ ctx_sprint((stretch and f_botaccent or f_fixedbotaccent)(name,0,family,slot))
elseif class == over_class then
ctx_sprint(f_over(name,0,family,slot))
elseif class == under_class then
ctx_sprint(f_under(name,0,family,slot))
elseif class == open_class or class == close_class or class == middle_class then
--- setdelcode("global",slot,{family,slot,0,0})
setdelcode("global",slot,family,slot,0,0)
- ctx_sprint(f_fence(name,class,family,slot))
+ ctx_sprint(f_fence(name,engine,family,slot))
elseif class == delimiter_class then
--- setdelcode("global",slot,{family,slot,0,0})
setdelcode("global",slot,family,slot,0,0)
ctx_sprint(f_delimiter(name,0,family,slot))
elseif class == radical_class then
@@ -231,29 +314,31 @@ do
elseif class == root_class then
ctx_sprint(f_root(name,family,slot))
elseif texmathchardef then
- texmathchardef(name,class,family,slot,"permanent")
+ texmathchardef(name,engine,family,slot,"permanent")
else
-- beware, open/close and other specials should not end up here
- ctx_sprint(f_char(name,class,family,slot))
+ ctx_sprint(f_char(name,engine,family,slot))
end
end
- local function report(class,family,unicode,name)
- local nametype = type(name)
- if nametype == "string" then
- report_math("class name %a, class %a, family %a, char %C, name %a",classname,class,family,unicode,name)
- elseif nametype == "number" then
- report_math("class name %a, class %a, family %a, char %C, number %U",classname,class,family,unicode,name)
- else
- report_math("class name %a, class %a, family %a, char %C", classname,class,family,unicode)
+ function mathematics.define()
+ if trace_defining then
+ logs.startfilelogging(report_math,"math defined from character definitions")
end
- end
-
- -- there will be a combined \(math)chardef (tracker)
-
- function mathematics.define() -- we now always use family zero
local family = 0
local data = characters.data
+ --
+ local function remap(first,last)
+ for unicode=utfbyte(first),utfbyte(last) do
+ setmathcode("global",unicode,ordinary_class,family,unicode)
+ end
+ end
+ remap("0","9")
+ remap("A","Z")
+ remap("a","z")
+ --
+ setdelcode("global",0x2E,0,0,0,0) -- period is special
+ --
for unicode, character in sortedhash(data) do
local symbol = character.mathsymbol
local mset = true
@@ -262,11 +347,11 @@ do
local other = data[symbol]
local class = other.mathclass
if class then
- class = classes[class] or class -- no real checks needed
+ local engine = toengineclass(class)
if trace_defining then
- report(class,family,unicode,symbol)
+ report(class,engine,family,unicode,symbol)
end
- mset, dset = setmathcharacter(class,family,unicode,symbol,mset,dset)
+ mset, dset = setmathcharacter(engine,family,unicode,symbol,mset,dset)
end
local spec = other.mathspec
if spec then
@@ -274,84 +359,103 @@ do
local m = spec[i]
local class = m.class
if class then
- class = classes[class] or class -- no real checks needed
- mset, dset = setmathcharacter(class,family,unicode,symbol,mset,dset)
+ local engine = toengineclass(class)
+ -- todo: trace
+ mset, dset = setmathcharacter(engine,family,unicode,symbol,mset,dset)
end
end
end
end
- local mathclass = character.mathclass
- local mathspec = character.mathspec
- if mathspec then
- if mathclass then
- local name = character.mathname
+ local class = character.mathclass
+ local spec = character.mathspec
+ local name = character.mathname
+ local stretch = character.mathstretch
+ if spec then
+ local done = false
+ if class then
if name then
report_math("fatal error, conflicting mathclass and mathspec for %C",unicode)
os.exit()
else
- local class = classes[mathclass] or mathclass -- no real checks needed
- if not class then
- if trace_defining then
- report("unknown",family,unicode)
- end
- else
- if trace_defining then
- report(class,family,unicode)
- end
- mset, dset = setmathcharacter(class,family,unicode,unicode,mset,dset)
+ class = classes[class] or ordinary_class
+ local engine = toengineclass(class)
+ if trace_defining then
+ report(class,engine,family,unicode)
end
+ mset, dset = setmathcharacter(engine,family,unicode,unicode,mset,dset)
+ done = true
end
end
- for i=1,#mathspec do
- local m = mathspec[i]
- local name = m.name
- local class = m.class
+ for i=1,#spec do
+ local m = spec[i]
+ local name = m.name
+ local class = m.class or class
if class then
- class = classes[class] or class -- no real checks needed
+ class = classes[class] or ordinary_class
+ else
+ class = ordinary_class
+ end
+ if class then
+ local engine = toengineclass(class)
if name then
if trace_defining then
- report(class,family,unicode,name)
+ report(class,engine,family,unicode,name)
end
- setmathsymbol(name,class,family,unicode)
+ setmathsymbol(name,class,engine,family,unicode,stretch)
else
- name = (class == classes.variable or class == classes.number) and character.adobename -- bad
+ name = (class == classes.ordinary or class == classes.digit) and character.adobename -- bad
if name and trace_defining then
- report(class,family,unicode,name)
+ report(class,engine,family,unicode,name)
end
end
- mset, dset = setmathcharacter(class,family,unicode,m.unicode or unicode,mset,dset) -- see solidus
+ if not done then
+ mset, dset = setmathcharacter(engine,family,unicode,m.unicode or unicode,mset,dset) -- see solidus
+ done = true
+ end
end
end
- elseif mathclass then
- local name = character.mathname
- local class = classes[mathclass] or mathclass -- no real checks needed
- if not class then
- if trace_defining then
- report("unknown",family,unicode,name)
- end
- elseif name == false then
- if trace_defining then
- report(class,family,unicode,name)
- end
- mset, dset = setmathcharacter(class,family,unicode,unicode,mset,dset)
+ else
+ if class then
+ class = classes[class] or ordinary_class
else
- -- if not name then
- -- name = character.contextname -- too dangerous, we loose textslash and a few more
- -- end
- if name then
+ class = ordinary_class
+ end
+ if name ~= nil then
+ local engine = toengineclass(class)
+ if name == false then
if trace_defining then
- report(class,family,unicode,name)
+ report(class,engine,family,unicode,name)
end
- setmathsymbol(name,class,family,unicode)
+ mset, dset = setmathcharacter(engine,family,unicode,unicode,mset,dset)
else
- if trace_defining then
- report(class,family,unicode,character.adobename)
+ -- if not name then
+ -- name = character.contextname -- too dangerous, we loose textslash and a few more
+ -- end
+ if name then
+ if trace_defining then
+ report(class,engine,family,unicode,name)
+ end
+ setmathsymbol(name,class,engine,family,unicode,stretch)
+ else
+ if trace_defining then
+ report(class,engine,family,unicode,character.adobename)
+ end
end
+ mset, dset = setmathcharacter(engine,family,unicode,unicode,mset,dset)
end
- mset, dset = setmathcharacter(class,family,unicode,unicode,mset,dset)
+ elseif class ~= ordinary_class then
+ local engine = toengineclass(class)
+ if trace_defining then
+ report(class,engine,family,unicode,character.adobename)
+ end
+ mset, dset = setmathcharacter(engine,family,unicode,unicode,mset,dset)
end
end
end
+ --
+ if trace_defining then
+ logs.stopfilelogging()
+ end
end
end
@@ -596,17 +700,19 @@ end
-- 2: step 2
-- 3: htdp * 1.33^n
-- 4: size * 1.33^n
+-- 5: use lfg
function mathematics.big(tfmdata,unicode,n,method)
local t = tfmdata.characters
local c = t[unicode]
if c and n > 0 then
- local vv = c.vvariants or c.next and t[c.next].vvariants
- if vv then
- local vvn = vv[n]
- return vvn and vvn.glyph or vv[#vv].glyph or unicode
- elseif method == 1 or method == 2 then
- if method == 2 then -- large steps
+ if method == 1 or method == 2 or method == 5 then
+ if method == 5 then
+ local b = tfmdata.bigslots
+ if b then
+ n = (n > #b and b[#b]) or b[n] or n
+ end
+ elseif method == 2 then -- large steps
n = n * 2
end
local next = c.next
@@ -754,7 +860,7 @@ implement {
-- weird to do this here but it's a side affect of math anyway
-interfaces.implement {
+implement {
name = "enableasciimode",
onlyonce = true,
actions = resolvers.macros.enablecomment,