diff options
Diffstat (limited to 'tex/context/base/mkxl/math-noa.lmt')
-rw-r--r-- | tex/context/base/mkxl/math-noa.lmt | 255 |
1 files changed, 112 insertions, 143 deletions
diff --git a/tex/context/base/mkxl/math-noa.lmt b/tex/context/base/mkxl/math-noa.lmt index 3699ae03c..e035a9f68 100644 --- a/tex/context/base/mkxl/math-noa.lmt +++ b/tex/context/base/mkxl/math-noa.lmt @@ -7,6 +7,9 @@ if not modules then modules = { } end modules ['math-noa'] = { license = "see context related readme files" } +-- if specials and (specials[1] == "char" or specials[1] == "font") then -- can we avoid this +-- ... better create a reverse mapping from the already present vectors + -- beware: this is experimental code and there will be a more generic (attribute value -- driven) interface too but for the moment this is ok (sometime in 2015-2016 i will -- start cleaning up as by then the bigger picture is clear and code has been used for @@ -108,6 +111,7 @@ local setattrlist = nuts.setattrlist local setwidth = nuts.setwidth local setheight = nuts.setheight local setdepth = nuts.setdepth +local setoptions = nuts.setoptions local getfield = nuts.getfield local getnext = nuts.getnext @@ -185,19 +189,22 @@ local nodecodes = nodes.nodecodes local noadcodes = nodes.noadcodes local fencecodes = nodes.fencecodes -local ordinarynoad_code = noadcodes.ordinary -local operatornoad_code = noadcodes.operator -local binarynoad_code = noadcodes.binary -local relationnoad_code = noadcodes.relation -local opennoad_code = noadcodes.open -local closenoad_code = noadcodes.close +local ordinarynoad_code = noadcodes.ordinary +local operatornoad_code = noadcodes.operator +local binarynoad_code = noadcodes.binary +local relationnoad_code = noadcodes.relation +local opennoad_code = noadcodes.open +local closenoad_code = noadcodes.close +local middlenoad_code = noadcodes.middle local punctuationnoad_code = noadcodes.punctuation -local innernoad_code = noadcodes.inner -local undernoad_code = noadcodes.under -local overnoad_code = noadcodes.over -local vcenternoad_code = noadcodes.vcenter -local fractionnoad_code = noadcodes.fraction -local radicalnoad_code = noadcodes.radical +local innernoad_code = noadcodes.inner +local fencednoad_code = noadcodes.fenced +local undernoad_code = noadcodes.under +local overnoad_code = noadcodes.over +local vcenternoad_code = noadcodes.vcenter +local fractionnoad_code = noadcodes.fraction +local radicalnoad_code = noadcodes.radical +local accentnoad_code = noadcodes.accent local noad_code = nodecodes.noad local accent_code = nodecodes.accent @@ -230,6 +237,8 @@ local rightfence_code = fencecodes.right -- local gf = getfield local gt = setmetatableindex("number") getfield = function(n,f) gt[f] = gt[f] + 1 return gf(n,f) end mathematics.GETFIELD = gt -- local sf = setfield local st = setmetatableindex("number") setfield = function(n,f,v) st[f] = st[f] + 1 sf(n,f,v) end mathematics.SETFIELD = st +-- TODO : get rid of done + local function process(start,what,n,parent) if n then @@ -280,10 +289,9 @@ local function process(start,what,n,parent) local noad = getnucleus(start) if noad then process(noad,what,n,start) end -- list noad = getsup (start) if noad then process(noad,what,n,start) end -- list noad = getsub (start) if noad then process(noad,what,n,start) end -- list - if getsubpre then noad = getsuppre (start) if noad then process(noad,what,n,start) end -- list noad = getsubpre (start) if noad then process(noad,what,n,start) end -- list - end + noad = getfield(start,"prime") if noad then process(noad,what,n,start) end -- list elseif id == mathchar_code or id == mathtextchar_code or id == delimiter_code then break elseif id == subbox_code or id == submlist_code then @@ -300,24 +308,24 @@ local function process(start,what,n,parent) noad = getfield(start,"scriptscript") if noad then process(noad,what,n,start) end -- list elseif id == fence_code then local noad = getfield(start,"delimiter") if noad then process(noad,what,n,start) end -- delimiter + noad = getfield(start,"top") if noad then process(noad,what,n,start) end -- list + noad = getfield(start,"bottom") if noad then process(noad,what,n,start) end -- list elseif id == radical_code then local noad = getnucleus(start) if noad then process(noad,what,n,start) end -- list noad = getsup (start) if noad then process(noad,what,n,start) end -- list noad = getsub (start) if noad then process(noad,what,n,start) end -- list - if getsubpre then noad = getsuppre (start) if noad then process(noad,what,n,start) end -- list noad = getsubpre (start) if noad then process(noad,what,n,start) end -- list - end + noad = getfield(start,"prime") if noad then process(noad,what,n,start) end -- delimiter noad = getfield(start,"left") if noad then process(noad,what,n,start) end -- delimiter noad = getfield(start,"degree") if noad then process(noad,what,n,start) end -- list elseif id == accent_code then local noad = getnucleus(start) if noad then process(noad,what,n,start) end -- list noad = getsup (start) if noad then process(noad,what,n,start) end -- list noad = getsub (start) if noad then process(noad,what,n,start) end -- list - if getsubpre then noad = getsuppre (start) if noad then process(noad,what,n,start) end -- list noad = getsubpre (start) if noad then process(noad,what,n,start) end -- list - end + noad = getfield(start,"prime") if noad then process(noad,what,n,start) end -- list noad = getfield(start,"topaccent") if noad then process(noad,what,n,start) end -- list noad = getfield(start,"botaccent") if noad then process(noad,what,n,start) end -- list -- elseif id == style_code then @@ -341,10 +349,9 @@ local function processnested(current,what,n) noad = getnucleus(current) if noad then process(noad,what,n,current) end -- list noad = getsup (current) if noad then process(noad,what,n,current) end -- list noad = getsub (current) if noad then process(noad,what,n,current) end -- list - if getsubpre then noad = getsuppre (current) if noad then process(noad,what,n,current) end -- list noad = getsubpre (current) if noad then process(noad,what,n,current) end -- list - end + noad = getfield (current,"prime") if noad then process(noad,what,n,current) end -- list elseif id == subbox_code or id == submlist_code then noad = getlist(current) if noad then process(noad,what,n,current) end -- list (not getlist !) elseif id == fraction_code then @@ -359,24 +366,24 @@ local function processnested(current,what,n) noad = getfield(current,"scriptscript") if noad then process(noad,what,n,current) end -- list elseif id == fence_code then noad = getfield(current,"delimiter") if noad then process(noad,what,n,current) end -- delimiter + noad = getfield(current,"top") if noad then process(noad,what,n,current) end -- list + noad = getfield(current,"bottom") if noad then process(noad,what,n,current) end -- list elseif id == radical_code then noad = getnucleus(current) if noad then process(noad,what,n,current) end -- list noad = getsup (current) if noad then process(noad,what,n,current) end -- list noad = getsub (current) if noad then process(noad,what,n,current) end -- list - if getsubpre then noad = getsuppre (current) if noad then process(noad,what,n,current) end -- list noad = getsubpre (current) if noad then process(noad,what,n,current) end -- list - end + noad = getfield(current,"prime") if noad then process(noad,what,n,current) end -- list noad = getfield(current,"left") if noad then process(noad,what,n,current) end -- delimiter noad = getfield(current,"degree") if noad then process(noad,what,n,current) end -- list elseif id == accent_code then noad = getnucleus(current) if noad then process(noad,what,n,current) end -- list noad = getsup (current) if noad then process(noad,what,n,current) end -- list noad = getsub (current) if noad then process(noad,what,n,current) end -- list - if getsubpre then noad = getsuppre (current) if noad then process(noad,what,n,current) end -- list noad = getsubpre (current) if noad then process(noad,what,n,current) end -- list - end + noad = getfield(current,"prime") if noad then process(noad,what,n,current) end -- list noad = getfield(current,"topaccent") if noad then process(noad,what,n,current) end -- list noad = getfield(current,"botaccent") if noad then process(noad,what,n,current) end -- list end @@ -389,10 +396,9 @@ local function processstep(current,process,n,id) noad = getnucleus(current) if noad then process(noad,n,current) end -- list noad = getsup (current) if noad then process(noad,n,current) end -- list noad = getsub (current) if noad then process(noad,n,current) end -- list - if getsubpre then noad = getsuppre (current) if noad then process(noad,n,current) end -- list noad = getsubpre (current) if noad then process(noad,n,current) end -- list - end + noad = getfield (current,"prime") if noad then process(noad,n,current) end -- list elseif id == subbox_code or id == submlist_code then noad = getlist(current) if noad then process(noad,n,current) end -- list (not getlist !) elseif id == fraction_code then @@ -407,24 +413,24 @@ local function processstep(current,process,n,id) noad = getfield(current,"scriptscript") if noad then process(noad,n,current) end -- list elseif id == fence_code then noad = getfield(current,"delimiter") if noad then process(noad,n,current) end -- delimiter + noad = getfield(current,"top") if noad then process(noad,n,current) end -- list + noad = getfield(current,"bottom") if noad then process(noad,n,current) end -- list elseif id == radical_code then noad = getnucleus(current) if noad then process(noad,n,current) end -- list noad = getsup (current) if noad then process(noad,n,current) end -- list noad = getsub (current) if noad then process(noad,n,current) end -- list - if getsubpre then noad = getsuppre (current) if noad then process(noad,n,current) end -- list noad = getsubpre (current) if noad then process(noad,n,current) end -- list - end + noad = getfield(current,"prime") if noad then process(noad,n,current) end -- delimiter noad = getfield(current,"left") if noad then process(noad,n,current) end -- delimiter noad = getfield(current,"degree") if noad then process(noad,n,current) end -- list elseif id == accent_code then noad = getnucleus(current) if noad then process(noad,n,current) end -- list noad = getsup (current) if noad then process(noad,n,current) end -- list noad = getsub (current) if noad then process(noad,n,current) end -- list - if getsubpre then noad = getsuppre (current) if noad then process(noad,n,current) end -- list noad = getsubpre (current) if noad then process(noad,n,current) end -- list - end + noad = getfield(current,"prime") if noad then process(noad,n,current) end -- list noad = getfield(current,"topaccent") if noad then process(noad,n,current) end -- list noad = getfield(current,"botaccent") if noad then process(noad,n,current) end -- list end @@ -837,40 +843,44 @@ end do + -- todo: use registerattribute + local a_mathsize = privateattribute("mathsize") -- this might move into other fence code local resize = { } resize[fence_code] = function(pointer) local subtype = getsubtype(pointer) - if subtype == leftfence_code or subtype == rightfence_code then + -- if subtype == leftfence_code or subtype == rightfence_code then local a = getattr(pointer,a_mathsize) if a and a > 0 then local method = div(a,100) local size = a % 100 setattr(pointer,a_mathsize,0) local delimiter = getfield(pointer,"delimiter") - local chr, fnt, fam = getcharspec(delimiter) - if chr > 0 and fnt > 0 then - local data = fontdata[fnt] - local char = mathematics.big(data,chr,size,method) - local ht = getheight(pointer) - local dp = getdepth(pointer) - if ht == 1 or dp == 1 then -- 1 scaled point is a signal - local chardata = data.characters[char] - if ht == 1 then - setheight(pointer,chardata.height) + if delimiter then + local chr, fnt, fam = getcharspec(delimiter) + if chr > 0 and fnt > 0 then + local data = fontdata[fnt] + local char = mathematics.big(data,chr,size,method) + local ht = getheight(pointer) + local dp = getdepth(pointer) + if ht == 1 or dp == 1 then -- 1 scaled point is a signal + local chardata = data.characters[char] + if ht == 1 then + setheight(pointer,chardata.height) + end + if dp == 1 then + setdepth(pointer,chardata.depth) + end end - if dp == 1 then - setdepth(pointer,chardata.depth) + if trace_fences then + report_fences("replacing %C by %C using method %a and size %a",chr,char,method,size) end + setchar(delimiter,char) end - if trace_fences then - report_fences("replacing %C by %C using method %a and size %a",chr,char,method,size) - end - setchar(delimiter,char) end end - end + -- end end function handlers.resize(head,style,penalties) @@ -930,7 +940,7 @@ do -- f_c or "?" -- ) local list = new_submlist() - setsubtype(noad,innernoad_code) + setsubtype(noad,fencednoad_code) setnucleus(noad,list) setlist(list,f_o) setlink(f_o,o_next) -- prev of list is nil @@ -993,8 +1003,8 @@ do local f_c = makefence(rightfence_code,close) local c_prev = getprev(close) local f_next = getnext(first) - makelist(middle, close, f_o,f_next,c_prev,f_c) - -- close is now a list + makelist(middle,close,f_o,f_next,c_prev,f_c) + -- close is now a list : inner but should be fenced if c_prev ~= first then setlink(first,close) end @@ -1003,7 +1013,7 @@ do local stacks = setmetatableindex("table") - -- 1=open 2=close 3=middle 4=both + -- 1=open 2=close 3=middle 4=both : todo check both local function processfences(pointer,n,parent) local current = pointer @@ -1811,14 +1821,17 @@ do [binarynoad_code] = true, -- new [relationnoad_code] = true, [opennoad_code] = true, -- new + [middlenoad_code] = true, -- new [closenoad_code] = true, -- new [punctuationnoad_code] = true, -- new [innernoad_code] = false, + [fencednoad_code] = false, [undernoad_code] = false, [overnoad_code] = false, [vcenternoad_code] = false, - [fractionnoad_code] = false, + [fractionnoad_code] = true, [radicalnoad_code] = false, + [accentnoad_code] = true, } local reported = setmetatableindex("table") @@ -1928,111 +1941,64 @@ do end do - -- inner under over vcenter + -- todo: make a primes class local fixscripts = { } --- local movesub = { --- -- primes --- [0x2032] = 0xFE932, --- [0x2033] = 0xFE933, --- [0x2034] = 0xFE934, --- [0x2057] = 0xFE957, --- -- reverse primes --- [0x2035] = 0xFE935, --- [0x2036] = 0xFE936, --- [0x2037] = 0xFE937, --- } --- --- mathematics.virtualize(movesub) - local movesub = { + local primes = { -- primes - [0x2032] = 0x2032, - [0x2033] = 0x2033, - [0x2034] = 0x2034, - [0x2057] = 0x2057, + [0x2032] = true, + [0x2033] = true, + [0x2034] = true, + [0x2057] = true, -- reverse primes - [0x2035] = 0x2035, - [0x2036] = 0x2036, - [0x2037] = 0x2037, + [0x2035] = true, + [0x2036] = true, + [0x2037] = true, } - local nosuperscript_code = tex.mathoptioncodes.nosuperscript - - local function fixsupscript(parent,current,current_char,new_char) - if new_char ~= current_char and new_char ~= true then - setchar(current,new_char) - if trace_fixing then - report_fixing("fixing subscript, replacing superscript %U by %U",current_char,new_char) - end - else - if trace_fixing then - report_fixing("fixing subscript, superscript %U",current_char) - end - end - setfield(parent,"options",nosuperscript_code) - end - - local function move_none_none(parent,prev,nuc,oldchar,newchar) - fixsupscript(prev,nuc,oldchar,newchar) - local sub = getsub(parent) - setsup(prev,nuc) - setsub(prev,sub) - local dummy = copy_node(nuc) - setchar(dummy,0) - setnucleus(parent,dummy) - setsub(parent) - end - - local function move_none_psub(parent,prev,nuc,oldchar,newchar) - fixsupscript(prev,nuc,oldchar,newchar) - setsup(prev,nuc) - local dummy = copy_node(nuc) - setchar(dummy,0) - setnucleus(parent,dummy) - end + local fixable = { + [noad_code] = true, + [accent_code] = true, + [radical_code] = true, + [fraction_code] = true, + } fixscripts[mathchar_code] = function(pointer,what,n,parent,nested) -- todo: switch to turn in on and off if parent then - local oldchar = getchar(pointer) - local newchar = movesub[oldchar] - if newchar then + local char = getchar(pointer) + if char and primes[char] then local nuc = getnucleus(parent) if pointer == nuc then - local sub = getsub(pointer) - local sup = getsup(pointer) - if sub then - if sup then - -- print("[char] sub sup") - else - -- print("[char] sub ---") + local prev = getprev(parent) + if prev and fixable[getid(prev)] then + local prevsup = getsup(prev) + local prevsub = getsub(prev) + local primesup = getsup(parent) + local primesub = getsub(parent) + setfield(prev,"scriptorder",prevsub and 2 or 1) -- sub first + if primesup and not prevsup then + setsup(prev,primesup) + primesup = nil end - elseif sup then - -- print("[char] --- sup") - else - local prev = getprev(parent) - if prev and getid(prev) == noad_code then - local psub = getsub(prev) - local psup = getsup(prev) - if psub then - if psup then - -- print("sub sup [char] --- ---") - else - -- print("sub --- [char] --- ---") - move_none_psub(parent,prev,nuc,oldchar,newchar) - end - elseif psup then - -- print("--- sup [char] --- ---") - else - -- print("[char] --- ---") - move_none_none(parent,prev,nuc,oldchar,newchar) - end - else - -- print("no prev [char]") + if primesub and not prevsub then + setsub(prev,primesub) + primesub = nil + end + setfield(prev,"prime",nuc) + setnucleus(parent) + if not primesup then + setsup(parent) + end + if not primesub then + setsub(parent) + end + if not (primesup or primesub) then + setlink(prev,getnext(parent)) + flushnode(parent) + return true, prev, prev end end - else - -- print("[char]") end end end @@ -2119,10 +2085,12 @@ do [ordinarynoad_code] = "trace:db", [binarynoad_code] = "trace:dg", [opennoad_code] = "trace:dm", + [middlenoad_code] = "trace:dm", [closenoad_code] = "trace:dm", [punctuationnoad_code] = "trace:dc", -- [operatornoad_code] = "", -- [innernoad_code = "", + -- [fencednoad_code = "", -- [undernoad_code] = "", -- [overnoad_code] = "", -- [vcenternoad_code] = "", @@ -2176,6 +2144,7 @@ do relation = relationnoad_code, punctuation = punctuationnoad_code, inner = innernoad_code, + fenced = fencednoad_code, -- fraction = fractionnoad_code, -- radical = radicalnoad_code, } |