diff options
Diffstat (limited to 'tex/context/base/spac-ver.lua')
-rw-r--r-- | tex/context/base/spac-ver.lua | 430 |
1 files changed, 195 insertions, 235 deletions
diff --git a/tex/context/base/spac-ver.lua b/tex/context/base/spac-ver.lua index 7d78d6c12..0035c4119 100644 --- a/tex/context/base/spac-ver.lua +++ b/tex/context/base/spac-ver.lua @@ -37,6 +37,7 @@ local nodes, node, trackers, attributes, context, commands, tex = nodes, node, local texlists = tex.lists local texgetdimen = tex.getdimen local texnest = tex.nest +local texgetbox = tex.getbox local variables = interfaces.variables @@ -62,41 +63,23 @@ local a_skiporder = attributes.private('skiporder') local a_snapmethod = attributes.private('snapmethod') local a_snapvbox = attributes.private('snapvbox') -local nuts = nodes.nuts -local tonode = nuts.tonode -local tonut = nuts.tonut -local ntostring = nuts.tostring - -local getfield = nuts.getfield -local setfield = nuts.setfield -local getnext = nuts.getnext -local getprev = nuts.getprev -local getid = nuts.getid -local getlist = nuts.getlist -local getattr = nuts.getattr -local setattr = nuts.setattr -local getsubtype = nuts.getsubtype -local getbox = nuts.getbox - -local find_node_tail = nuts.tail -local free_node = nuts.free -local free_node_list = nuts.flush_list -local copy_node = nuts.copy -local traverse_nodes = nuts.traverse -local traverse_nodes_id = nuts.traverse_id -local insert_node_before = nuts.insert_before -local insert_node_after = nuts.insert_after -local remove_node = nuts.remove -local count_nodes = nuts.count -local hpack_node = nuts.hpack -local vpack_node = nuts.vpack -local writable_spec = nuts.writable_spec -local nodereference = nuts.reference - -local listtoutf = nodes.listtoutf +local find_node_tail = node.tail +local free_node = node.free +local free_node_list = node.flush_list +local copy_node = node.copy +local traverse_nodes = node.traverse +local traverse_nodes_id = node.traverse_id +local insert_node_before = node.insert_before +local insert_node_after = node.insert_after +local remove_node = nodes.remove +local count_nodes = nodes.count local nodeidstostring = nodes.idstostring +local hpack_node = node.hpack +local vpack_node = node.vpack +local writable_spec = nodes.writable_spec +local listtoutf = nodes.listtoutf -local nodepool = nuts.pool +local nodepool = nodes.pool local new_penalty = nodepool.penalty local new_kern = nodepool.kern @@ -196,26 +179,28 @@ end -- local rule_id = nodecodes.rule -- local vlist_id = nodecodes.vlist -- function nodes.makevtop(n) --- if getid(n) == vlist_id then --- local list = getlist(n) --- local height = (list and getid(list) <= rule_id and getfield(list,"height")) or 0 --- setfield(n,"depth",getfield(n,"depth") - height + getfield(n,"height") --- setfield(n,"height",height +-- if n.id == vlist_id then +-- local list = n.list +-- local height = (list and list.id <= rule_id and list.height) or 0 +-- n.depth = n.depth - height + n.height +-- n.height = height -- end -- end +local reference = nodes.reference + local function validvbox(parentid,list) if parentid == hlist_code then - local id = getid(list) + local id = list.id if id == whatsit_code then -- check for initial par subtype - list = getnext(list) + list = list.next if not next then return nil end end local done = nil for n in traverse_nodes(list) do - local id = getid(n) + local id = n.id if id == vlist_code or id == hlist_code then if done then return nil @@ -229,9 +214,9 @@ local function validvbox(parentid,list) end end if done then - local id = getid(done) + local id = done.id if id == hlist_code then - return validvbox(id,getlist(done)) + return validvbox(id,done.list) end end return done -- only one vbox @@ -241,19 +226,19 @@ end local function already_done(parentid,list,a_snapmethod) -- todo: done when only boxes and all snapped -- problem: any snapped vbox ends up in a line if list and parentid == hlist_code then - local id = getid(list) + local id = list.id if id == whatsit_code then -- check for initial par subtype - list = getnext(list) + list = list.next if not next then return false end end --~ local i = 0 for n in traverse_nodes(list) do - local id = getid(n) ---~ i = i + 1 print(i,nodecodes[id],getattr(n,a_snapmethod)) + local id = n.id +--~ i = i + 1 print(i,nodecodes[id],n[a_snapmethod]) if id == hlist_code or id == vlist_code then - local a = getattr(n,a_snapmethod) + local a = n[a_snapmethod] if not a then -- return true -- not snapped at all elseif a == 0 then @@ -291,11 +276,11 @@ end -- check variables.none etc local function snap_hlist(where,current,method,height,depth) -- method.strut is default - local list = getlist(current) + local list = current.list local t = trace_vsnapping and { } if t then t[#t+1] = formatters["list content: %s"](listtoutf(list)) - t[#t+1] = formatters["parent id: %s"](nodereference(current)) + t[#t+1] = formatters["parent id: %s"](reference(current)) t[#t+1] = formatters["snap method: %s"](method.name) t[#t+1] = formatters["specification: %s"](method.specification) end @@ -327,8 +312,7 @@ local function snap_hlist(where,current,method,height,depth) -- method.strut is t[#t+1] = formatters["auto: snapht %p snapdp %p"](snapht,snapdp) end end - local h = height or getfield(current,"height") - local d = depth or getfield(current,"depth") + local h, d = height or current.height, depth or current.depth local hr, dr, ch, cd = method.hfraction or 1, method.dfraction or 1, h, d local tlines, blines = method.tlines or 1, method.blines or 1 local done, plusht, plusdp = false, snapht, snapdp @@ -355,22 +339,22 @@ local function snap_hlist(where,current,method,height,depth) -- method.strut is if method.first then local thebox = current - local id = getid(thebox) + local id = thebox.id if id == hlist_code then - thebox = validvbox(id,getlist(thebox)) - id = thebox and getid(thebox) + thebox = validvbox(id,thebox.list) + id = thebox and thebox.id end if thebox and id == vlist_code then - local list = getlist(thebox) + local list = thebox.list local lh, ld for n in traverse_nodes_id(hlist_code,list) do - lh = getfield(n,"height") - ld = getfield(n,"depth") + lh = n.height + ld = n.depth break end if lh then - local ht = getfield(thebox,"height") - local dp = getfield(thebox,"depth") + local ht = thebox.height + local dp = thebox.depth if t then t[#t+1] = formatters["first line: height %p depth %p"](lh,ld) t[#t+1] = formatters["dimensions: height %p depth %p"](ht,dp) @@ -378,9 +362,9 @@ local function snap_hlist(where,current,method,height,depth) -- method.strut is local delta = h - lh ch, cd = lh, delta + d h, d = ch, cd - local shifted = hpack_node(getlist(current)) - setfield(shifted,"shift",delta) - setfield(current,"list",shifted) + local shifted = hpack_node(current.list) + shifted.shift = delta + current.list = shifted done = true if t then t[#t+1] = formatters["first: height %p depth %p shift %p"](ch,cd,delta) @@ -393,21 +377,20 @@ local function snap_hlist(where,current,method,height,depth) -- method.strut is end elseif method.last then local thebox = current - local id = getid(thebox) + local id = thebox.id if id == hlist_code then - thebox = validvbox(id,getlist(thebox)) - id = thebox and getid(thebox) + thebox = validvbox(id,thebox.list) + id = thebox and thebox.id end if thebox and id == vlist_code then - local list = getlist(thebox) - local lh, ld + local list, lh, ld = thebox.list for n in traverse_nodes_id(hlist_code,list) do - lh = getfield(n,"height") - ld = getfield(n,"depth") + lh = n.height + ld = n.depth end if lh then - local ht = getfield(thebox,"height") - local dp = getfield(thebox,"depth") + local ht = thebox.height + local dp = thebox.depth if t then t[#t+1] = formatters["last line: height %p depth %p" ](lh,ld) t[#t+1] = formatters["dimensions: height %p depth %p"](ht,dp) @@ -415,9 +398,9 @@ local function snap_hlist(where,current,method,height,depth) -- method.strut is local delta = d - ld cd, ch = ld, delta + h h, d = ch, cd - local shifted = hpack_node(getlist(current)) - setfield(shifted,"shift",delta) - setfield(current,"list",shifted) + local shifted = hpack_node(current.list) + shifted.shift = delta + current.list = shifted done = true if t then t[#t+1] = formatters["last: height %p depth %p shift %p"](ch,cd,delta) @@ -478,25 +461,25 @@ local function snap_hlist(where,current,method,height,depth) -- method.strut is if offset then -- we need to set the attr if t then - t[#t+1] = formatters["before offset: %p (width %p height %p depth %p)"](offset,getfield(current,"width"),getfield(current,"height"),getfield(current,"depth")) + t[#t+1] = formatters["before offset: %p (width %p height %p depth %p)"](offset,current.width,current.height,current.depth) end - local shifted = hpack_node(getlist(current)) - setfield(shifted,"shift",offset) - setfield(current,"list",shifted) + local shifted = hpack_node(current.list) + shifted.shift = offset + current.list = shifted if t then - t[#t+1] = formatters["after offset: %p (width %p height %p depth %p)"](offset,getfield(current,"width"),getfield(current,"height"),getfield(current,"depth")) + t[#t+1] = formatters["after offset: %p (width %p height %p depth %p)"](offset,current.width,current.height,current.depth) end - setattr(shifted,a_snapmethod,0) - setattr(current,a_snapmethod,0) + shifted[a_snapmethod] = 0 + current[a_snapmethod] = 0 end if not height then - setfield(current,"height",ch) + current.height = ch if t then t[#t+1] = formatters["forced height: %p"](ch) end end if not depth then - setfield(current,"depth",cd) + current.depth = cd if t then t[#t+1] = formatters["forced depth: %p"](cd) end @@ -510,17 +493,17 @@ local function snap_hlist(where,current,method,height,depth) -- method.strut is t[#t+1] = formatters["final depth: %p -> %p"](d,cd) end if t then - report_snapper("trace: %s type %s\n\t%\n\tt",where,nodecodes[getid(current)],t) + report_snapper("trace: %s type %s\n\t%\n\tt",where,nodecodes[current.id],t) end return h, d, ch, cd, lines end local function snap_topskip(current,method) - local spec = getfield(current,"spec") - local w = getfield(spec,"width") + local spec = current.spec + local w = spec.width local wd = w - if getfield(spec,"writable") then - setfield(spec,"width",0) + if spec.writable then + spec.width = 0 wd = 0 end return w, wd @@ -681,18 +664,18 @@ local trace_list, tracing_info, before, after = { }, false, "", "" local function nodes_to_string(head) local current, t = head, { } while current do - local id = getid(current) + local id = current.id local ty = nodecodes[id] if id == penalty_code then - t[#t+1] = formatters["%s:%s"](ty,getfield(current,"penalty")) + t[#t+1] = formatters["%s:%s"](ty,current.penalty) elseif id == glue_code then -- or id == kern_code then -- to be tested t[#t+1] = formatters["%s:%p"](ty,current) elseif id == kern_code then - t[#t+1] = formatters["%s:%p"](ty,getfield(current,"kern")) + t[#t+1] = formatters["%s:%p"](ty,current.kern) else t[#t+1] = ty end - current = getnext(current) + current = current.next end return concat(t," + ") end @@ -716,7 +699,7 @@ local function trace_info(message, where, what) end local function trace_node(what) - local nt = nodecodes[getid(what)] + local nt = nodecodes[what.id] local tl = trace_list[#trace_list] if tl and tl[1] == "node" then trace_list[#trace_list] = { "node", formatters["%s + %s"](tl[2],nt) } @@ -726,8 +709,8 @@ local function trace_node(what) end local function trace_done(str,data) - if getid(data) == penalty_code then - trace_list[#trace_list+1] = { "penalty", formatters["%s | %s"](str,getfield(data,"penalty")) } + if data.id == penalty_code then + trace_list[#trace_list+1] = { "penalty", formatters["%s | %s"](str,data.penalty) } else trace_list[#trace_list+1] = { "glue", formatters["%s | %p"](str,data) } end @@ -765,31 +748,22 @@ local belowdisplayshortskip_code = skipcodes.belowdisplayshortskip local topskip_code = skipcodes.topskip local splittopskip_code = skipcodes.splittopskip --- local function free_glue_node(n) --- free_node(n) --- local s = getfield(n,"spec") --- if s then --- free_node(s) --- end --- end - local free_glue_node = free_node -local free_glue_spec = function() end -- free_node function vspacing.snapbox(n,how) local sv = snapmethods[how] if sv then - local box = getbox(n) - local list = getlist(box) + local box = texgetbox(n) + local list = box.list if list then - local s = getattr(list,a_snapmethod) + local s = list[a_snapmethod] if s == 0 then if trace_vsnapping then -- report_snapper("box list not snapped, already done") end else - local ht = getfield(box,"height") - local dp = getfield(box,"depth") + local ht = box.height + local dp = box.depth if false then -- todo: already_done -- assume that the box is already snapped if trace_vsnapping then @@ -798,14 +772,14 @@ function vspacing.snapbox(n,how) end else local h, d, ch, cd, lines = snap_hlist("box",box,sv,ht,dp) - setfield(box,"height",ch) - setfield(box,"depth",cd) + box.height= ch + box.depth = cd if trace_vsnapping then report_snapper("box list snapped from (%p,%p) to (%p,%p) using method %a (%s) for %a (%s lines): %s", h,d,ch,cd,sv.name,sv.specification,"direct",lines,listtoutf(list)) end - setattr(box,a_snapmethod,0) -- - setattr(list,a_snapmethod,0) -- yes or no + box[a_snapmethod] = 0 -- + list[a_snapmethod] = 0 -- yes or no end end end @@ -827,10 +801,8 @@ local w, h, d = 0, 0, 0 ----- w, h, d = 100*65536, 65536, 65536 local function forced_skip(head,current,width,where,trace) - if head == current then - if getsubtype(head) == baselineskip_code then - width = width - getfield(getfield(head,"spec"),"width") - end + if head == current and head.subtype == baselineskip_code then + width = width - head.spec.width end if width == 0 then -- do nothing @@ -862,25 +834,25 @@ local special_penalty_max = 35000 local function specialpenalty(start,penalty) -- nodes.showsimplelist(texlists.page_head,1) - local current = find_node_tail(tonut(texlists.page_head)) -- no texlists.page_tail yet + local current = find_node_tail(texlists.page_head) while current do - local id = getid(current) + local id = current.id if id == glue_code then - current = getprev(current) + current = current.prev elseif id == penalty_code then - local p = getfield(current,"penalty") + local p = current.penalty if p == penalty then if trace_vspacing then report_vspacing("overloading penalty %a",p) end return current elseif p >= 10000 then - current = getprev(current) + current = current.prev else break end else - current = getprev(current) + current = current.prev end end end @@ -903,12 +875,12 @@ local function collapser(head,where,what,trace,snap,a_snapmethod) -- maybe also head = insert_node_before(head,current,p) end if glue_data then - local spec = getfield(glue_data,"spec") + local spec = glue_data.spec if force_glue then if trace then trace_done("flushed due to " .. why,glue_data) end - head = forced_skip(head,current,getfield(spec,"width"),"before",trace) + head = forced_skip(head,current,spec.width,"before",trace) free_glue_node(glue_data) - elseif getfield(spec,"writable") then + elseif spec.writable then if trace then trace_done("flushed due to " .. why,glue_data) end head = insert_node_before(head,current,glue_data) else @@ -928,12 +900,12 @@ local function collapser(head,where,what,trace,snap,a_snapmethod) -- maybe also end if trace then trace_info("start analyzing",where,what) end while current do - local id = getid(current) + local id = current.id if id == hlist_code or id == vlist_code then -- needs checking, why so many calls if snap then - local list = getlist(current) - local s = getattr(current,a_snapmethod) + local list = current.list + local s = current[a_snapmethod] if not s then -- if trace_vsnapping then -- report_snapper("mvl list not snapped") @@ -947,8 +919,8 @@ local function collapser(head,where,what,trace,snap,a_snapmethod) -- maybe also if sv then -- check if already snapped if list and already_done(id,list,a_snapmethod) then - local ht = getfield(current,"height") - local dp = getfield(current,"depth") + local ht = current.height + local dp = current.depth -- assume that the box is already snapped if trace_vsnapping then report_snapper("mvl list already snapped at (%p,%p): %s",ht,dp,listtoutf(list)) @@ -963,39 +935,40 @@ local function collapser(head,where,what,trace,snap,a_snapmethod) -- maybe also elseif trace_vsnapping then report_snapper("mvl %a not snapped due to unknown snap specification: %s",nodecodes[id],listtoutf(list)) end - setattr(current,a_snapmethod,0) + current[a_snapmethod] = 0 end else -- end -- tex.prevdepth = 0 flush("list") - current = getnext(current) + current = current.next elseif id == penalty_code then - -- natural_penalty = getfield(current,"penalty") + -- natural_penalty = current.penalty -- if trace then trace_done("removed penalty",current) end -- head, current = remove_node(head, current, true) - current = getnext(current) + current = current.next elseif id == kern_code then - if snap and trace_vsnapping and getfield(current,"kern") ~= 0 then - report_snapper("kern of %p kept",getfield(current,"kern")) + if snap and trace_vsnapping and current.kern ~= 0 then + report_snapper("kern of %p kept",current.kern) end flush("kern") - current = getnext(current) + current = current.next elseif id == glue_code then - local subtype = getsubtype(current) + local subtype = current.subtype if subtype == userskip_code then - local sc = getattr(current,a_skipcategory) -- has no default, no unset (yet) - local so = getattr(current,a_skiporder) or 1 -- has 1 default, no unset (yet) - local sp = getattr(current,a_skippenalty) -- has no default, no unset (yet) + local sc = current[a_skipcategory] -- has no default, no unset (yet) + local so = current[a_skiporder] or 1 -- has 1 default, no unset (yet) + local sp = current[a_skippenalty] -- has no default, no unset (yet) if sp and sc == penalty then - if where == "page" and sp >= special_penalty_min and sp <= special_penalty_max then - local previousspecial = specialpenalty(current,sp) - if previousspecial then - setfield(previousspecial,"penalty",0) - sp = 0 - end - end + +if where == "page" and sp >= special_penalty_min and sp <= special_penalty_max then + local previousspecial = specialpenalty(current,sp) + if previousspecial then + previousspecial.penalty = 0 + sp = 0 + end +end if not penalty_data then penalty_data = sp elseif penalty_order < so then @@ -1010,38 +983,37 @@ local function collapser(head,where,what,trace,snap,a_snapmethod) -- maybe also if trace then trace_done("flush",glue_data) end head = insert_node_before(head,current,glue_data) if trace then trace_natural("natural",current) end - current = getnext(current) + current = current.next else -- not look back across head -- todo: prev can be whatsit (latelua) - local previous = getprev(current) - if previous and getid(previous) == glue_code and getsubtype(previous) == userskip_code then - local ps = getfield(previous,"spec") - if getfield(ps,"writable") then - local cs = getfield(current,"spec") - if getfield(cs,"writable") and getfield(ps,"stretch_order") == 0 and getfield(ps,"shrink_order") == 0 and getfield(cs,"stretch_order") == 0 and getfield(cs,"shrink_order") == 0 then - local pw, pp, pm = getfield(ps,"width"), getfield(ps,"stretch"), getfield(ps,"shrink") - local cw, cp, cm = getfield(cs,"width"), getfield(cs,"stretch"), getfield(cs,"shrink") + local previous = current.prev + if previous and previous.id == glue_code and previous.subtype == userskip_code then + local ps = previous.spec + if ps.writable then + local cs = current.spec + if cs.writable and ps.stretch_order == 0 and ps.shrink_order == 0 and cs.stretch_order == 0 and cs.shrink_order == 0 then + local pw, pp, pm = ps.width, ps.stretch, ps.shrink + local cw, cp, cm = cs.width, cs.stretch, cs.shrink -- ps = writable_spec(previous) -- no writable needed here -- ps.width, ps.stretch, ps.shrink = pw + cw, pp + cp, pm + cm - free_glue_spec(ps) - setfield(previous,"spec",new_gluespec(pw + cw, pp + cp, pm + cm)) -- else topskip can disappear + previous.spec = new_gluespec(pw + cw, pp + cp, pm + cm) -- else topskip can disappear if trace then trace_natural("removed",current) end head, current = remove_node(head, current, true) -- current = previous if trace then trace_natural("collapsed",previous) end - -- current = getnext(current) + -- current = current.next else if trace then trace_natural("filler",current) end - current = getnext(current) + current = current.next end else if trace then trace_natural("natural (no prev spec)",current) end - current = getnext(current) + current = current.next end else if trace then trace_natural("natural (no prev)",current) end - current = getnext(current) + current = current.next end end glue_order, glue_data = 0, nil @@ -1074,12 +1046,12 @@ local function collapser(head,where,what,trace,snap,a_snapmethod) -- maybe also elseif glue_order == so then -- is now exclusive, maybe support goback as combi, else why a set if sc == largest then - local cs, gs = getfield(current,"spec"), getfield(glue_data,"spec") - local cw, gw = getfield(cs,"width"), getfield(gs,"width") + local cs, gs = current.spec, glue_data.spec + local cw, gw = cs.width, gs.width if cw > gw then if trace then trace_skip("largest",sc,so,sp,current) end free_glue_node(glue_data) -- also free spec - head, current, glue_data = remove_node(head,current) + head, current, glue_data = remove_node(head, current) else if trace then trace_skip("remove smallest",sc,so,sp,current) end head, current = remove_node(head, current, true) @@ -1087,7 +1059,7 @@ local function collapser(head,where,what,trace,snap,a_snapmethod) -- maybe also elseif sc == goback then if trace then trace_skip("goback",sc,so,sp,current) end free_glue_node(glue_data) -- also free spec - head, current, glue_data = remove_node(head,current) + head, current, glue_data = remove_node(head, current) elseif sc == force then -- last one counts, some day we can provide an accumulator and largest etc -- but not now @@ -1101,11 +1073,11 @@ local function collapser(head,where,what,trace,snap,a_snapmethod) -- maybe also head, current = remove_node(head, current, true) elseif sc == add then if trace then trace_skip("add",sc,so,sp,current) end - -- local old, new = glue_data.spec, getfield(current,"spec") - local old, new = writable_spec(glue_data), getfield(current,"spec") - setfield(old,"width",getfield(old,"width") + getfield(new,"width")) - setfield(old,"stretch",getfield(old,"stretch") + getfield(new,"stretch")) - setfield(old,"shrink",getfield(old,"shrink") + getfield(new,"shrink")) + -- local old, new = glue_data.spec, current.spec + local old, new = writable_spec(glue_data), current.spec + old.width = old.width + new.width + old.stretch = old.stretch + new.stretch + old.shrink = old.shrink + new.shrink -- toto: order head, current = remove_node(head, current, true) else @@ -1121,13 +1093,12 @@ local function collapser(head,where,what,trace,snap,a_snapmethod) -- maybe also end elseif subtype == lineskip_code then if snap then - local s = getattr(current,a_snapmethod) + local s = current[a_snapmethod] if s and s ~= 0 then - setattr(current,a_snapmethod,0) - local spec = getfield(current,"spec") - if getfield(spec,"writable") then + current[a_snapmethod] = 0 + if current.spec.writable then local spec = writable_spec(current) - setfield(spec,"width",0) + spec.width = 0 if trace_vsnapping then report_snapper("lineskip set to zero") end @@ -1140,16 +1111,15 @@ local function collapser(head,where,what,trace,snap,a_snapmethod) -- maybe also if trace then trace_skip("lineskip",sc,so,sp,current) end flush("lineskip") end - current = getnext(current) + current = current.next elseif subtype == baselineskip_code then if snap then - local s = getattr(current,a_snapmethod) + local s = current[a_snapmethod] if s and s ~= 0 then - setattr(current,a_snapmethod,0) - local spec = getfield(current,"spec") - if getfield(spec,"writable") then + current[a_snapmethod] = 0 + if current.spec.writable then local spec = writable_spec(current) - setfield(spec,"width",0) + spec.width = 0 if trace_vsnapping then report_snapper("baselineskip set to zero") end @@ -1162,17 +1132,17 @@ local function collapser(head,where,what,trace,snap,a_snapmethod) -- maybe also if trace then trace_skip("baselineskip",sc,so,sp,current) end flush("baselineskip") end - current = getnext(current) + current = current.next elseif subtype == parskip_code then -- parskip always comes later if ignore_whitespace then if trace then trace_natural("ignored parskip",current) end head, current = remove_node(head, current, true) elseif glue_data then - local ps = getfield(current,"spec") - local gs = getfield(glue_data,"spec") - if getfield(ps,"writable") and getfield(gs,"writable") and getfield(ps,"width") > getfield(gs,"width") then - setfield(glue_data,"spec",copy_node(ps)) + local ps = current.spec + local gs = glue_data.spec + if ps.writable and gs.writable and ps.width > gs.width then + glue_data.spec = copy_node(ps) if trace then trace_natural("taking parskip",current) end else if trace then trace_natural("removed parskip",current) end @@ -1184,9 +1154,9 @@ local function collapser(head,where,what,trace,snap,a_snapmethod) -- maybe also end elseif subtype == topskip_code or subtype == splittopskip_code then if snap then - local s = getattr(current,a_snapmethod) + local s = current[a_snapmethod] if s and s ~= 0 then - setattr(current,a_snapmethod,0) + current[a_snapmethod] = 0 local sv = snapmethods[s] local w, cw = snap_topskip(current,sv) if trace_vsnapping then @@ -1200,46 +1170,46 @@ local function collapser(head,where,what,trace,snap,a_snapmethod) -- maybe also if trace then trace_skip("topskip",sc,so,sp,current) end flush("topskip") end - current = getnext(current) + current = current.next elseif subtype == abovedisplayskip_code then -- if trace then trace_skip("above display skip (normal)",sc,so,sp,current) end flush("above display skip (normal)") - current = getnext(current) + current = current.next -- elseif subtype == belowdisplayskip_code then -- if trace then trace_skip("below display skip (normal)",sc,so,sp,current) end flush("below display skip (normal)") - current = getnext(current) - -- + current = current.next + -- elseif subtype == abovedisplayshortskip_code then -- if trace then trace_skip("above display skip (short)",sc,so,sp,current) end flush("above display skip (short)") - current = getnext(current) + current = current.next -- elseif subtype == belowdisplayshortskip_code then -- if trace then trace_skip("below display skip (short)",sc,so,sp,current) end flush("below display skip (short)") - current = getnext(current) + current = current.next -- else -- other glue if snap and trace_vsnapping then - local spec = getfield(current,"spec") - if getfield(spec,"writable") and getfield(spec,"width") ~= 0 then - report_snapper("glue %p of type %a kept",getfield(spec,"width"),skipcodes[subtype]) - -- setfield(spec,"width",0) + local spec = current.spec + if spec.writable and spec.width ~= 0 then + report_snapper("glue %p of type %a kept",current.spec.width,skipcodes[subtype]) + -- spec.width = 0 end end - if trace then trace_skip(formatters["glue of type %a"](subtype),sc,so,sp,current) end + if trace then trace_skip(formatter["glue of type %a"](subtype),sc,so,sp,current) end flush("some glue") - current = getnext(current) + current = current.next end else - flush(formatters["node with id %a"](id)) - current = getnext(current) + flush("something else") + current = current.next end end if trace then trace_info("stop analyzing",where,what) end @@ -1260,8 +1230,7 @@ local function collapser(head,where,what,trace,snap,a_snapmethod) -- maybe also if not tail then tail = find_node_tail(head) end if trace then trace_done("result",glue_data) end if force_glue then - local spec = getfield(glue_data,"spec") - head, tail = forced_skip(head,tail,getfield(spec,"width"),"after",trace) + head, tail = forced_skip(head,tail,glue_data.spec.width,"after",trace) free_glue_node(glue_data) else head, tail = insert_node_after(head,tail,glue_data) @@ -1274,7 +1243,7 @@ texnest[texnest.ptr].prevdepth = 0 -- appending to the list bypasses tex's prevd end show_tracing(head) if oldhead ~= head then - trace_info("head has been changed from %a to %a",nodecodes[getid(oldhead)],nodecodes[getid(head)]) + trace_info("head has been changed from %a to %a",nodecodes[oldhead.id],nodecodes[head.id]) end end return head, true @@ -1302,17 +1271,16 @@ end function vspacing.pagehandler(newhead,where) -- local newhead = texlists.contrib_head if newhead then - newhead = tonut(newhead) local newtail = find_node_tail(newhead) -- best pass that tail, known anyway local flush = false stackhack = true -- todo: only when grid snapping once enabled -- todo: fast check if head = tail for n in traverse_nodes(newhead) do -- we could just look for glue nodes - local id = getid(n) + local id = n.id if id ~= glue_code then flush = true - elseif getsubtype(n) == userskip_code then - if getattr(n,a_skipcategory) then + elseif n.subtype == userskip_code then + if n[a_skipcategory] then stackhack = true else flush = true @@ -1324,36 +1292,35 @@ function vspacing.pagehandler(newhead,where) if flush then if stackhead then if trace_collect_vspacing then report("appending %s nodes to stack (final): %s",newhead) end - setfield(stacktail,"next",newhead) - setfield(newhead,"prev",stacktail) + stacktail.next = newhead + newhead.prev = stacktail newhead = stackhead stackhead, stacktail = nil, nil end if stackhack then stackhack = false if trace_collect_vspacing then report("processing %s nodes: %s",newhead) end - -- texlists.contrib_head = collapser(newhead,"page",where,trace_page_vspacing,true,a_snapmethod) - newhead = collapser(newhead,"page",where,trace_page_vspacing,true,a_snapmethod) + -- texlists.contrib_head = collapser(newhead,"page",where,trace_page_vspacing,true,a_snapmethod) + newhead = collapser(newhead,"page",where,trace_page_vspacing,true,a_snapmethod) else if trace_collect_vspacing then report("flushing %s nodes: %s",newhead) end -- texlists.contrib_head = newhead end - return tonode(newhead) else if stackhead then if trace_collect_vspacing then report("appending %s nodes to stack (intermediate): %s",newhead) end - setfield(stacktail,"next",newhead) - setfield(newhead,"prev",stacktail) + stacktail.next = newhead + newhead.prev = stacktail else if trace_collect_vspacing then report("storing %s nodes in stack (initial): %s",newhead) end stackhead = newhead end stacktail = newtail -- texlists.contrib_head = nil - -- newhead = nil + newhead = nil end end - return nil + return newhead end local ignore = table.tohash { @@ -1363,23 +1330,18 @@ local ignore = table.tohash { } function vspacing.vboxhandler(head,where) - if head and not ignore[where] then - local h = tonut(head) - if getnext(h) then - h = collapser(h,"vbox",where,trace_vbox_vspacing,true,a_snapvbox) -- todo: local snapper - return tonode(h) - end + if head and not ignore[where] and head.next then + head = collapser(head,"vbox",where,trace_vbox_vspacing,true,a_snapvbox) -- todo: local snapper end return head end function vspacing.collapsevbox(n) -- for boxes but using global a_snapmethod - local box = getbox(n) + local box = texgetbox(n) if box then - local list = getlist(box) + local list = box.list if list then - list = collapser(list,"snapper","vbox",trace_vbox_vspacing,true,a_snapmethod) - setfield(box,"list",vpack_node(list)) + box.list = vpack_node(collapser(list,"snapper","vbox",trace_vbox_vspacing,true,a_snapmethod)) end end end @@ -1390,9 +1352,7 @@ end local outer = texnest[0] function vspacing.resetprevdepth() - if texlists.hold_head then - outer.prevdepth = 0 - end + outer.prevdepth = 0 end -- interface |