diff options
Diffstat (limited to 'Master/texmf-dist/tex/context/base/mkiv/math-noa.lua')
-rw-r--r-- | Master/texmf-dist/tex/context/base/mkiv/math-noa.lua | 212 |
1 files changed, 127 insertions, 85 deletions
diff --git a/Master/texmf-dist/tex/context/base/mkiv/math-noa.lua b/Master/texmf-dist/tex/context/base/mkiv/math-noa.lua index 37676722740..f53410b18cd 100644 --- a/Master/texmf-dist/tex/context/base/mkiv/math-noa.lua +++ b/Master/texmf-dist/tex/context/base/mkiv/math-noa.lua @@ -28,7 +28,7 @@ local utfchar, utfbyte = utf.char, utf.byte local formatters, gmatch = string.formatters, string.gmatch local sortedhash = table.sortedhash local insert, remove = table.insert, table.remove -local div = math.div +local div, round = math.div, math.round local bor, band = bit32.bor, bit32.band local fonts = fonts @@ -136,8 +136,6 @@ local set_visual = nuts.setvisual local mlist_to_hlist = nuts.mlist_to_hlist -local font_of_family = node.family_font - local new_kern = nodepool.kern local new_submlist = nodepool.submlist local new_noad = nodepool.noad @@ -152,6 +150,7 @@ local fontitalics = fonthashes.italics local variables = interfaces.variables local texsetattribute = tex.setattribute local texgetattribute = tex.getattribute +local getfontoffamily = tex.getfontoffamily local unsetvalue = attributes.unsetvalue local implement = interfaces.implement @@ -177,15 +176,19 @@ local noadcodes = nodes.noadcodes local fencecodes = nodes.fencecodes local ordnoad_code = noadcodes.ord -local relnode_code = noadcodes.rel +local opdisplaylimitsnoad_code = noadcodes.opdisplaylimits +local oplimitsnoad_code = noadcodes.oplimits +local opnolimitsnoad_code = noadcodes.opnolimits local binnoad_code = noadcodes.bin +local relnode_code = noadcodes.rel local opennoad_code = noadcodes.open local closenoad_code = noadcodes.close local punctnoad_code = noadcodes.punct -local opdisplaylimitsnoad_code = noadcodes.opdisplaylimits -local oplimitsnoad_code = noadcodes.oplimits -local opnolimitsnoad_code = noadcodes.opnolimits local innernoad_code = noadcodes.inner +local undernoad_code = noadcodes.under +local overnoad_code = noadcodes.over +local vcenternoad_code = noadcodes.vcenter +local ordlimitsnoad_code = noadcodes.ordlimits or oplimitsnoad_code local noad_code = nodecodes.noad -- attr nucleus sub sup local accent_code = nodecodes.accent -- attr nucleus sub sup accent @@ -197,6 +200,7 @@ local mathchar_code = nodecodes.mathchar -- attr fam char local mathtextchar_code = nodecodes.mathtextchar -- attr fam char local delim_code = nodecodes.delim -- attr small_fam small_char large_fam large_char ----- style_code = nodecodes.style -- attr style +----- parameter_code = nodecodes.parameter -- attr style local math_choice = nodecodes.choice -- attr display text script scriptscript local fence_code = nodecodes.fence -- attr subtype @@ -299,6 +303,8 @@ local function process(start,what,n,parent) noad = getfield(start,"bot_accent") if noad then process(noad,what,n,start) end -- list -- elseif id == style_code then -- -- has a next + -- elseif id == parameter_code then + -- -- has a next -- else -- -- glue, penalty, etc end @@ -505,7 +511,7 @@ do report_families("no bold replacement for %C, family %s with remap %s becomes %s with remap %s",char,a,familymap[a],newa,familymap[newa]) end setfam(pointer,newa) - elseif not fontcharacters[font_of_family(newa)][bold] then + elseif not fontcharacters[getfontoffamily(newa)][bold] then if trace_families then report_families("no bold character for %C, family %s with remap %s becomes %s with remap %s",char,a,familymap[a],newa,familymap[newa]) end @@ -522,7 +528,7 @@ do end else local char = getchar(pointer) - if not fontcharacters[font_of_family(a)][char] then + if not fontcharacters[getfontoffamily(a)][char] then if trace_families then report_families("no bold replacement for %C",char) end @@ -546,14 +552,14 @@ do a = a - 3 end local char = getfield(pointer,"small_char") - local okay = fontcharacters[font_of_family(a)][char] + local okay = fontcharacters[getfontoffamily(a)][char] if okay then setfield(pointer,"small_fam",a) elseif a > 2 then setfield(pointer,"small_fam",a-3) end local char = getfield(pointer,"large_char") - local okay = fontcharacters[font_of_family(a)][char] + local okay = fontcharacters[getfontoffamily(a)][char] if okay then setfield(pointer,"large_fam",a) elseif a > 2 then @@ -578,7 +584,7 @@ do -- a = a - 3 -- end -- local char = getchar(pointer) - -- local okay = fontcharacters[font_of_family(a)][char] + -- local okay = fontcharacters[getfontoffamily(a)][char] -- if okay then -- setfam(pointer,a) -- elseif a > 2 then @@ -785,7 +791,7 @@ do local chr = getchar(delimiter) if chr > 0 then local fam = getfam(delimiter) - local id = font_of_family(fam) + local id = getfontoffamily(fam) if id > 0 then local data = fontdata[id] local char = mathematics.big(data,chr,size,method) @@ -835,8 +841,8 @@ do if chr == dummyfencechar then chr = 0 end - setfield(d,"small_char",chr) - setfield(d,"small_fam",fam) + setchar(d,chr) + setfam(d,fam) flush_node(sym) end setattrlist(d,char) @@ -847,100 +853,102 @@ do return f end - -- will become - - -- local function makefence(what,char) - -- local d = new_delimiter() -- todo: attr - -- local f = new_fence() -- todo: attr - -- if char then - -- local sym = getnucleus(char) - -- local chr = getchar(sym) - -- local fam = getfam(sym) - -- if chr == dummyfencechar then - -- chr = 0 - -- end - -- setchar(d,chr) - -- setfam(d,fam) - -- flush_node(sym) - -- end - -- setsubtype(f,what) - -- setfield(f,"delim",d) - -- setfield(f,"class",-1) -- tex itself does this, so not fenceclasses[what] - -- return f - -- end - - local function makelist(noad,f_o,o_next,c_prev,f_c,middle) + local function show(where,pointer) + print("") + local i = 0 + for n in nuts.traverse(pointer) do + i = i + 1 + print(i,where,nuts.tonode(n)) + end + print("") + end + + local function makelist(middle,noad,f_o,o_next,c_prev,f_c) +-- report_fences( +-- "middle %s, noad %s, open %s, opennext %s, closeprev %s, close %s", +-- middle or "?", +-- noad or "?", +-- f_o or "?", +-- o_next or "?", +-- c_prev or "?", +-- f_c or "?" +-- ) local list = new_submlist() - setlist(list,f_o) setsubtype(noad,innernoad_code) setnucleus(noad,list) - setlink(f_o,o_next) - setlink(c_prev,f_c) + setlist(list,f_o) + setlink(f_o,o_next) -- prev of list is nil + setlink(c_prev,f_c) -- next of list is nil +-- show("list",f_o) if middle and next(middle) then local prev = f_o local current = o_next while current ~= f_c do - local m = middle[current] - if m then - local next = getnext(current) + local midl = middle[current] + local next = getnext(current) + if midl then local fence = makefence(middlefence_code,current) setnucleus(current) flush_node(current) middle[current] = nil -- replace_node setlink(prev,fence,next) - prev = fence - current = next + prev = fence else prev = current - current = getnext(current) end + current = next end end + return noad end + -- relinking is now somewhat overdone + local function convert_both(open,close,middle) - local o_prev, o_next = getboth(open) - local c_prev, c_next = getboth(close) + local o_next = getnext(open) if o_next == close then return close else + local c_prev, c_next = getboth(close) local f_o = makefence(leftfence_code,open) local f_c = makefence(rightfence_code,close) - makelist(open,f_o,o_next,c_prev,f_c,middle) + makelist(middle,open,f_o,o_next,c_prev,f_c) setnucleus(close) flush_node(close) - if c_next then - setprev(c_next,open) - end - setnext(open,c_next) + -- open is now a list + setlink(open,c_next) return open end end - local function convert_open(open,last,middle) + local function convert_open(open,last,middle) -- last is really last (final case) local f_o = makefence(leftfence_code,open) local f_c = makefence(rightfence_code) - local o_prev, o_next = getboth(open) - local l_prev, l_next = getboth(last) - makelist(open,f_o,o_next,last,f_c,middle) - if l_next then - setprev(l_next,open) - end - setnext(open,l_next) + local o_next = getnext(open) + makelist(middle,open,f_o,o_next,last,nil) + -- open is now a list + setlink(open,l_next) return open end - local function convert_close(close,first,middle) + local function convert_close(first,close,middle) local f_o = makefence(leftfence_code) local f_c = makefence(rightfence_code,close) local c_prev = getprev(close) - makelist(close,f_o,first,c_prev,f_c,middle) + local f_next = getnext(first) + makelist(middle, close, f_o,f_next,c_prev,f_c) + -- close is now a list + if c_prev ~= first then + setlink(first,close) + end return close end local stacks = setmetatableindex("table") + -- 1=open 2=close 3=middle 4=both + local function processfences(pointer,n,parent) local current = pointer local last = pointer @@ -950,47 +958,75 @@ do local stack = nil local middle = nil -- todo: use properties while current do +-- show("before",pointer) local id = getid(current) if id == noad_code then local a = getattr(current,a_autofence) if a and a > 0 then local stack = stacks[n] - setattr(current,a_autofence,0) - if a == 1 or (a == 4 and (not stack or #stack == 0)) then + setattr(current,a_autofence,0) -- hm, better use a property + local level = #stack + if a == 1 then if trace_fences then - report_fences("%2i: pushing open on stack",n) + report_fences("%2i: level %i, handling %s, action %s",n,level,"open","open") end insert(stack,current) - elseif a == 2 or a == 4 then + elseif a == 2 then local open = remove(stack) if open then if trace_fences then - report_fences("%2i: handling %s, stack depth %i",n,"both",#stack+1) + report_fences("%2i: level %i, handling %s, action %s",n,level,"close","both") end current = convert_both(open,current,middle) elseif current == start then - -- skip + if trace_fences then + report_fences("%2i: level %i, handling %s, action %s",n,level,"close","skip") + end else if trace_fences then - report_fences("%2i: handling %s, stack depth %i",n,"close",#stack+1) + report_fences("%2i: level %i, handling %s, action %s",n,level,"close","close") end - current = convert_close(current,initial,middle) + current = convert_close(initial,current,middle) if not parent then initial = current end end - if trace_fences then - report_fences("%2i: popping close from stack",n) - end elseif a == 3 then if trace_fences then - report_fences("%2i: registering middle",n) + report_fences("%2i: level %i, handling %s, action %s",n,level,"middle","middle") end if middle then middle[current] = last else middle = { [current] = last } end + elseif a == 4 then + if not stack or #stack == 0 then + if trace_fences then + report_fences("%2i: level %i, handling %s, action %s",n,level,"both","open") + end + insert(stack,current) + else + local open = remove(stack) + if open then + if trace_fences then + report_fences("%2i: level %i, handling %s, action %s",n,level,"both","both") + end + current = convert_both(open,current,middle) + elseif current == start then + if trace_fences then + report_fences("%2i: level %i, handling %s, action %s",n,level,"both","skip") + end + else + if trace_fences then + report_fences("%2i: level %i, handling %s, action %s",n,level,"both","close") + end + current = convert_close(initial,current,middle) + if not parent then + initial = current + end + end + end end done = true else @@ -1000,6 +1036,7 @@ do -- next at current level processstep(current,processfences,n,id) end +-- show("after",pointer) last = current current = getnext(current) end @@ -1007,16 +1044,14 @@ do local stack = stacks[n] local s = #stack if s > 0 then - if trace_fences then - report_fences("%2i: handling %s stack levels",n,s) - end for i=1,s do local open = remove(stack) if trace_fences then - report_fences("%2i: handling %s, stack depth %i",n,"open",#stack) + report_fences("%2i: level %i, handling %s, action %s",n,#stack,"flush","open") end last = convert_open(open,last,middle) end +-- show("done",pointer) end end end @@ -1326,7 +1361,7 @@ do local fontresources = fonts.hashes.resources local function getalternate(fam,tag,current) - local resources = fontresources[font_of_family(fam)] + local resources = fontresources[getfontoffamily(fam)] local attribute = unsetvalue if resources then local mathalternates = resources.mathalternates @@ -1557,6 +1592,7 @@ do else correction = correction - 100 end + correction = round(correction) setattr(pointer,a_mathitalics,correction) setattr(parent,a_mathitalics,correction) return -- so no reset later on @@ -1714,14 +1750,19 @@ do local mathlists = characters.mathlists local validpair = { [ordnoad_code] = true, - [relnode_code] = true, + [opdisplaylimitsnoad_code] = true, + [oplimitsnoad_code] = true, + [opnolimitsnoad_code] = true, [binnoad_code] = true, -- new + [relnode_code] = true, [opennoad_code] = true, -- new [closenoad_code] = true, -- new [punctnoad_code] = true, -- new - [opdisplaylimitsnoad_code] = true, - [oplimitsnoad_code] = true, - [opnolimitsnoad_code] = true, + [innernoad_code] = false, + [undernoad_code] = false, + [overnoad_code] = false, + [vcenternoad_code] = false, + [ordlimitsnoad_code] = true, } local reported = setmetatableindex("table") @@ -2043,6 +2084,7 @@ do -- [opdisplaylimitsnoad_code] = "", -- [oplimitsnoad_code] = "", -- [opnolimitsnoad_code] = "", + -- [ordlimitsnoad_code] = "", -- [innernoad_code = "", -- [undernoad_code] = "", -- [overnoad_code] = "", |