diff options
Diffstat (limited to 'Master/texmf-dist/tex/context/base/math-ini.lua')
-rw-r--r-- | Master/texmf-dist/tex/context/base/math-ini.lua | 404 |
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 |