diff options
Diffstat (limited to 'tex/context/base/typo-mar.lua')
-rw-r--r-- | tex/context/base/typo-mar.lua | 145 |
1 files changed, 85 insertions, 60 deletions
diff --git a/tex/context/base/typo-mar.lua b/tex/context/base/typo-mar.lua index 85d5c85a8..a41a409dd 100644 --- a/tex/context/base/typo-mar.lua +++ b/tex/context/base/typo-mar.lua @@ -115,13 +115,31 @@ local v_first = variables.first local v_text = variables.text local v_column = variables.column -local copy_node_list = node.copy_list -local slide_nodes = node.slide -local hpack_nodes = node.hpack -- nodes.fasthpack not really faster here -local traverse_id = node.traverse_id -local free_node_list = node.flush_list -local insert_node_after = node.insert_after -local insert_node_before = node.insert_before +local nuts = nodes.nuts +local nodepool = nuts.pool + +local tonode = nuts.tonode +local tonut = nuts.tonut + +local copy_node_list = nuts.copy_list +local slide_nodes = nuts.slide +local hpack_nodes = nuts.hpack -- nodes.fasthpack not really faster here +local traverse_id = nuts.traverse_id +local free_node_list = nuts.flush_list +local insert_node_after = nuts.insert_after +local insert_node_before = nuts.insert_before +local linked_nodes = nuts.linked + +local getfield = nuts.getfield +local setfield = nuts.setfield +local getnext = nuts.getnext +local getprev = nuts.getprev +local getid = nuts.getid +local getattr = nuts.getattr +local setattr = nuts.setattr +local getsubtype = nuts.getsubtype +local getbox = nuts.getbox +local getlist = nuts.getlist local nodecodes = nodes.nodecodes local listcodes = nodes.listcodes @@ -144,7 +162,7 @@ local userdefined_code = whatsitcodes.userdefined local dir_code = whatsitcodes.dir local localpar_code = whatsitcodes.localpar -local nodepool = nodes.pool +local nodepool = nuts.pool local new_kern = nodepool.kern local new_glue = nodepool.glue @@ -155,13 +173,12 @@ local new_latelua = nodepool.latelua local texgetcount = tex.getcount local texgetdimen = tex.getdimen -local texgetbox = tex.getbox local texget = tex.get local points = number.points local isleftpage = layouts.status.isleftpage -local registertogether = builders.paragraphs.registertogether +local registertogether = builders.paragraphs.registertogether -- tonode local jobpositions = job.positions local getposition = jobpositions.position @@ -170,7 +187,7 @@ local a_margindata = attributes.private("margindata") local inline_mark = nodepool.userids["margins.inline"] -local margins = { } +local margins = { } typesetters.margins = margins local locations = { v_left, v_right, v_inner, v_outer } -- order might change @@ -242,7 +259,7 @@ end function margins.save(t) setmetatable(t,defaults) - local content = texgetbox(t.number) + local content = getbox(t.number) local location = t.location local category = t.category local inline = t.inline @@ -310,11 +327,11 @@ function margins.save(t) -- nice is to make a special status table mechanism local leftmargindistance = texgetdimen("naturalleftmargindistance") local rightmargindistance = texgetdimen("naturalrightmargindistance") - local strutbox = texgetbox("strutbox") - t.strutdepth = strutbox.depth - t.strutheight = strutbox.height - t.leftskip = texget("leftskip").width -- we're not in forgetall - t.rightskip = texget("rightskip").width -- we're not in forgetall + local strutbox = getbox("strutbox") + t.strutdepth = getfield(strutbox,"depth") + t.strutheight = getfield(strutbox,"height") + t.leftskip = getfield(texget("leftskip"),"width") -- we're not in forgetall + t.rightskip = getfield(texget("rightskip"),"width") -- we're not in forgetall t.leftmargindistance = leftmargindistance -- todo:layoutstatus table t.rightmargindistance = rightmargindistance t.leftedgedistance = texgetdimen("naturalleftedgedistance") @@ -404,7 +421,7 @@ local function realign(current,candidate) -- we assume that list is a hbox, otherwise we had to take the whole current -- in order to get it right - current.width = 0 + setfield(current,"width",0) local anchornode, move_x -- this mess is needed for alignments (combinations) so we use that @@ -446,9 +463,9 @@ local function realign(current,candidate) report_margindata("realigned %a, location %a, margin %a",candidate.n,location,margin) end end - - current.list = hpack_nodes(anchornode .. new_kern(-delta) .. current.list .. new_kern(delta)) - current.width = 0 + local list = hpack_nodes(linked_nodes(anchornode,new_kern(-delta),getlist(current),new_kern(delta))) + setfield(current,"list",list) + setfield(current,"width",0) end local function realigned(current,a) @@ -490,7 +507,8 @@ local function markovershoot(current) v_anchors = v_anchors + 1 cache[v_anchors] = stacked local anchor = new_latelua(format("typesetters.margins.ha(%s)",v_anchors)) -- todo: alleen als offset > line - current.list = hpack_nodes(anchor .. current.list) + local list = hpack_nodes(linked_nodes(anchor,getlist(current))) + setfield(current,"list",list) end local function getovershoot(location) @@ -512,10 +530,10 @@ end local function inject(parent,head,candidate) local box = candidate.box - local width = box.width - local height = box.height - local depth = box.depth - local shift = box.shift + local width = getfield(box,"width") + local height = getfield(box,"height") + local depth = getfield(box,"depth") + local shift = getfield(box,"shift") local stack = candidate.stack local location = candidate.location local method = candidate.method @@ -524,7 +542,7 @@ local function inject(parent,head,candidate) local baseline = candidate.baseline local strutheight = candidate.strutheight local strutdepth = candidate.strutdepth - local psubtype = parent.subtype + local psubtype = getsubtype(parent) local offset = stacked[location] local firstonstack = offset == false or offset == nil nofstatus = nofstatus + 1 @@ -546,7 +564,7 @@ local function inject(parent,head,candidate) end end candidate.width = width - candidate.hsize = parent.width -- we can also pass textwidth + candidate.hsize = getfield(parent,"width") -- we can also pass textwidth candidate.psubtype = psubtype if trace_margindata then report_margindata("processing, index %s, height %p, depth %p, parent %s",candidate.n,height,depth,listcodes[psubtype]) @@ -573,7 +591,7 @@ local function inject(parent,head,candidate) -- experimental. -- -- -- if method == v_top then - local delta = height - parent.height + local delta = height - getfield(parent,"height") if trace_margindata then report_margindata("top aligned by %p",delta) end @@ -616,22 +634,23 @@ local function inject(parent,head,candidate) shift = shift + delta offset = offset + delta end - box.shift = shift - box.width = 0 + setfield(box,"shift",shift) + setfield(box,"width",0) if not head then head = box - elseif head.id == whatsit_code and head.subtype == localpar_code then + elseif getid(head) == whatsit_code and getsubtype(head) == localpar_code then -- experimental - if head.dir == "TRT" then - box.list = hpack_nodes(new_kern(candidate.hsize) .. box.list .. new_kern(-candidate.hsize)) + if getfield(head,"dir") == "TRT" then + local list = hpack_nodes(linked_nodes(new_kern(candidate.hsize),getlist(box),new_kern(-candidate.hsize))) + setfield(box,"list",list) end insert_node_after(head,head,box) else - head.prev = box - box.next = head + setfield(head,"prev",box) + setfield(box,"next",head) head = box end - box[a_margindata] = nofstatus + setfield(box,a_margindata,nofstatus) if trace_margindata then report_margindata("injected, location %a, shift %p",location,shift) end @@ -656,12 +675,12 @@ local function flushinline(parent,head) local current = head local done = false local continue = false - local room, don, con + local room, don, con, list while current and nofinlined > 0 do - local id = current.id + local id = getid(current) if id == whatsit_code then - if current.subtype == userdefined_code and current.user_id == inline_mark then - local n = current.value + if getsubtype(current) == userdefined_code and getfield(current,"user_id") == inline_mark then + local n = getfield(current,"value") local candidate = inlinestore[n] if candidate then -- no vpack, as we want to realign inlinestore[n] = nil @@ -674,11 +693,12 @@ local function flushinline(parent,head) end elseif id == hlist_code or id == vlist_code then -- optional (but sometimes needed) - current.list, don, con = flushinline(current,current.list) + list, don, con = flushinline(current,getlist(current)) + setfield(current,"list",list) continue = continue or con done = done or don end - current = current.next + current = getnext(current) end return head, done, continue end @@ -686,7 +706,7 @@ end local a_linenumber = attributes.private('linenumber') local function flushed(scope,parent) -- current is hlist - local head = parent.list + local head = getlist(parent) local done = false local continue = false local room, con, don @@ -702,7 +722,7 @@ local function flushed(scope,parent) -- current is hlist done = true continue = continue or con nofstored = nofstored - 1 - registertogether(parent,room) + registertogether(tonode(parent),room) -- !! tonode else break end @@ -711,17 +731,18 @@ local function flushed(scope,parent) -- current is hlist end if nofinlined > 0 then if done then - parent.list = head + setfield(parent,"list",head) end head, don, con = flushinline(parent,head) continue = continue or con done = done or don end if done then - local a = head[a_linenumber] -- hack .. we need a more decent critical attribute inheritance mechanism - parent.list = hpack_nodes(head,parent.width,"exactly") + local a = getattr(head,a_linenumber) -- hack .. we need a more decent critical attribute inheritance mechanism + local l = hpack_nodes(head,getfield(parent,"width"),"exactly") + setfield(parent,"list",l) if a then - parent.list[a_linenumber] = a + setattr(l,a_linenumber,a) end -- resetstacked() end @@ -736,14 +757,15 @@ local function handler(scope,head,group) if trace_margindata then report_margindata("flushing stage one, stored %s, scope %s, delayed %s, group %a",nofstored,scope,nofdelayed,group) end + head = tonut(head) local current = head local done = false while current do - local id = current.id - if (id == vlist_code or id == hlist_code) and not current[a_margindata] then + local id = getid(current) + if (id == vlist_code or id == hlist_code) and not getattr(current,a_margindata) then local don, continue = flushed(scope,current) if don then - current[a_margindata] = 0 -- signal to prevent duplicate processing + setattr(current,a_margindata,0) -- signal to prevent duplicate processing if continue then markovershoot(current) end @@ -753,12 +775,12 @@ local function handler(scope,head,group) done = true end end - current = current.next + current = getnext(current) end -- if done then resetstacked() -- why doesn't done work ok here? -- end - return head, done + return tonode(head), done else return head, false end @@ -811,11 +833,11 @@ local function finalhandler(head) local current = head local done = false while current do - local id = current.id + local id = getid(current) if id == hlist_code then - local a = current[a_margindata] + local a = getattr(current,a_margindata) if not a or a == 0 then - finalhandler(current.list) + finalhandler(getlist(current)) elseif realigned(current,a) then done = true if nofdelayed == 0 then @@ -823,9 +845,9 @@ local function finalhandler(head) end end elseif id == vlist_code then - finalhandler(current.list) + finalhandler(getlist(current)) end - current = current.next + current = getnext(current) end return head, done else @@ -838,7 +860,10 @@ function margins.finalhandler(head) -- if trace_margindata then -- report_margindata("flushing stage two, instore: %s, delayed: %s",nofstored,nofdelayed) -- end - return finalhandler(head) +head = tonut(head) +local head, done = finalhandler(head) +head = tonode(head) + return head, done else return head, false end |