diff options
author | Hans Hagen <pragma@wxs.nl> | 2017-02-17 10:31:56 +0100 |
---|---|---|
committer | Context Git Mirror Bot <phg42.2a@gmail.com> | 2017-02-17 10:31:56 +0100 |
commit | b14f992ef5f4e868c9959b174278c86516d60dbc (patch) | |
tree | 28587bb46c025ea7b0d27ba93f09c93dcf53c73a /tex/context/base/mkiv/spac-ver.lua | |
parent | 95a1799032dc61dbca4a11e495be34b4397c8fec (diff) | |
download | context-b14f992ef5f4e868c9959b174278c86516d60dbc.tar.gz |
2017-02-17 10:23:00
Diffstat (limited to 'tex/context/base/mkiv/spac-ver.lua')
-rw-r--r-- | tex/context/base/mkiv/spac-ver.lua | 342 |
1 files changed, 175 insertions, 167 deletions
diff --git a/tex/context/base/mkiv/spac-ver.lua b/tex/context/base/mkiv/spac-ver.lua index 37f99e760..c7eec18ee 100644 --- a/tex/context/base/mkiv/spac-ver.lua +++ b/tex/context/base/mkiv/spac-ver.lua @@ -30,6 +30,8 @@ if not modules then modules = { } end modules ['spac-ver'] = { -- todo: strip baselineskip around display math +-- todo: getglue(n,false) instead of getfield + local next, type, tonumber = next, type, tonumber local gmatch, concat = string.gmatch, table.concat local ceil, floor = math.ceil, math.floor @@ -39,8 +41,6 @@ local allocate = utilities.storage.allocate local todimen = string.todimen local formatters = string.formatters -local P, C, R, S, Cc, Carg = lpeg.P, lpeg.C, lpeg.R, lpeg.S, lpeg.Cc, lpeg.Carg - local nodes = nodes local node = node local trackers = trackers @@ -62,7 +62,7 @@ local implement = interfaces.implement local v_local = variables["local"] local v_global = variables["global"] local v_box = variables.box -local v_page = variables.page -- reserved for future use +----- v_page = variables.page -- reserved for future use local v_split = variables.split local v_min = variables.min local v_max = variables.max @@ -136,15 +136,23 @@ local getprop = nuts.getprop local setprop = nuts.setprop local getglue = nuts.getglue local setglue = nuts.setglue +local getkern = nuts.getkern +local getpenalty = nuts.getpenalty +local setshift = nuts.setshift +local setwidth = nuts.setwidth +local getwidth = nuts.getwidth +local setheight = nuts.setheight +local getheight = nuts.getheight +local setdepth = nuts.setdepth +local getdepth = nuts.getdepth local find_node_tail = nuts.tail local flush_node = nuts.flush_node 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 count_nodes = nuts.countall local hpack_node = nuts.hpack local vpack_node = nuts.vpack ----- writable_spec = nuts.writable_spec @@ -266,17 +274,6 @@ function vspacing.definesnapmethod(name,method) context(n) 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 --- end --- end - local function validvbox(parentid,list) if parentid == hlist_code then local id = getid(list) @@ -326,16 +323,16 @@ local function already_done(parentid,list,a_snapmethod) -- todo: done when only for n in traverse_nodes(list) do local id = getid(n) if id == hlist_code or id == vlist_code then --- local a = getattr(n,a_snapmethod) --- if not a then --- -- return true -- not snapped at all --- elseif a == 0 then --- return true -- already snapped --- end -local p = getprop(n,"snapper") -if p then - return p -end + -- local a = getattr(n,a_snapmethod) + -- if not a then + -- -- return true -- not snapped at all + -- elseif a == 0 then + -- return true -- already snapped + -- end + local p = getprop(n,"snapper") + if p then + return p + end elseif id == glue_code or id == penalty_code then -- or id == kern_code then -- go on else @@ -517,7 +514,7 @@ local function snap_hlist(where,current,method,height,depth) -- method[v_strut] ch, cd = lh, delta + d h, d = ch, cd local shifted = hpack_node(getlist(current)) - setfield(shifted,"shift",delta) + setshift(shifted,delta) setlist(current,shifted) done = true if t then @@ -552,7 +549,7 @@ local function snap_hlist(where,current,method,height,depth) -- method[v_strut] cd, ch = ld, delta + h h, d = ch, cd local shifted = hpack_node(getlist(current)) - setfield(shifted,"shift",delta) + setshift(shifted,delta) setlist(current,shifted) done = true if t then @@ -618,7 +615,7 @@ local function snap_hlist(where,current,method,height,depth) -- method[v_strut] t[#t+1] = formatters["before offset: %p (width %p height %p depth %p)"](offset,wd,ht,dp) end local shifted = hpack_node(getlist(current)) - setfield(shifted,"shift",offset) + setshift(shifted,offset) setlist(current,shifted) if t then local wd, ht, dp = getwhd(current) @@ -628,13 +625,13 @@ local function snap_hlist(where,current,method,height,depth) -- method[v_strut] setattr(current,a_snapmethod,0) end if not height then - setfield(current,"height",ch) + setheight(current,ch) if t then t[#t+1] = formatters["forced height: %p"](ch) end end if not depth then - setfield(current,"depth",cd) + setdepth(current,cd) if t then t[#t+1] = formatters["forced depth: %p"](cd) end @@ -664,8 +661,8 @@ local function snap_hlist(where,current,method,height,depth) -- method[v_strut] end local function snap_topskip(current,method) - local w = getfield(current,"width") or 0 - setfield(current,"width",0) + local w = getwidth(current) + setwidth(current,0) return w, 0 end @@ -714,6 +711,8 @@ storage.register("builders/vspacing/data/skip", vspacingdata.skip, "builders.vsp do -- todo: interface.variables and properties + local P, C, R, S, Cc = lpeg.P, lpeg.C, lpeg.R, lpeg.S, lpeg.Cc + vspacing.fixed = false local map = vspacingdata.map @@ -834,11 +833,11 @@ local function nodes_to_string(head) local id = getid(current) 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,getpenalty(current)) elseif id == glue_code then - t[#t+1] = formatters["%s:%s:%p"](ty,skipcodes[getsubtype(current)],getfield(current,"width")) + t[#t+1] = formatters["%s:%s:%p"](ty,skipcodes[getsubtype(current)],getwidth(current)) elseif id == kern_code then - t[#t+1] = formatters["%s:%p"](ty,getfield(current,"kern")) + t[#t+1] = formatters["%s:%p"](ty,getkern(current)) else t[#t+1] = ty end @@ -852,12 +851,12 @@ local function reset_tracing(head) end local function trace_skip(str,sc,so,sp,data) - trace_list[#trace_list+1] = { "skip", formatters["%s | %p | category %s | order %s | penalty %s"](str, getfield(data,"width"), sc or "-", so or "-", sp or "-") } + trace_list[#trace_list+1] = { "skip", formatters["%s | %p | category %s | order %s | penalty %s"](str, getwidth(data), sc or "-", so or "-", sp or "-") } tracing_info = true end local function trace_natural(str,data) - trace_list[#trace_list+1] = { "skip", formatters["%s | %p"](str, getfield(data,"width")) } + trace_list[#trace_list+1] = { "skip", formatters["%s | %p"](str, getwidth(data)) } tracing_info = true end @@ -877,9 +876,9 @@ 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")) } + trace_list[#trace_list+1] = { "penalty", formatters["%s | %s"](str,getpenalty(data)) } else - trace_list[#trace_list+1] = { "glue", formatters["%s | %p"](str,getfield(data,"width")) } + trace_list[#trace_list+1] = { "glue", formatters["%s | %p"](str,getwidth(data)) } end tracing_info = true end @@ -958,10 +957,10 @@ end local w, h, d = 0, 0, 0 ----- w, h, d = 100*65536, 65536, 65536 -local function forced_skip(head,current,width,where,trace) +local function forced_skip(head,current,width,where,trace) -- looks old ... we have other tricks now if head == current then if getsubtype(head) == baselineskip_code then - width = width - (getfield(head,"width") or 0) + width = width - getwidth(head) end end if width == 0 then @@ -1057,7 +1056,7 @@ specialmethods[1] = function(pagehead,pagetail,start,penalty) report_specials(" context penalty %a, higher level, continue",p) end else - local p = getfield(current,"penalty") + local p = getpenalty(current) if p < 10000 then -- assume some other mechanism kicks in so we seem to have content if trace_specials then @@ -1101,15 +1100,15 @@ local function check_experimental_overlay(head,current) local skips = 0 -- -- We deal with this at the tex end .. we don't see spacing .. enabling this code - -- is probably harmless btu then we need to test it. + -- is probably harmless but then we need to test it. -- local c = getnext(p) while c and c ~= n do local id = getid(c) if id == glue_code then - skips = skips + (getfield(c,"width") or 0) + skips = skips + getwidth(c) elseif id == kern_code then - skips = skips + getfield(c,"kern") + skips = skips + getkern(c) end c = getnext(c) end @@ -1119,7 +1118,7 @@ local function check_experimental_overlay(head,current) local k = new_kern(-delta) if n_ht > p_ht then -- we should adapt pagetotal ! (need a hook for that) .. now we have the wrong pagebreak - setfield(p,"height",n_ht) + setheight(p,n_ht) end insert_node_before(head,n,k) if p == head then @@ -1230,18 +1229,18 @@ local function collapser(head,where,what,trace,snap,a_snapmethod) -- maybe also local function compensate(n) local g = 0 while n and getid(n) == glue_code do - g = g + getfield(n,"width") + g = g + getwidth(n) n = getnext(n) end if n then local p = getprop(n,"snapper") if p then local extra = p.extra - if extra < 0 then - local h = p.ch -- getfield(n,"height") + if extra and extra < 0 then -- hm, extra can be unset ... needs checking + local h = p.ch -- getheight(n) -- maybe an extra check -- if h - extra < g then - setfield(n,"height",h-2*extra) + setheight(n,h-2*extra) p.extra = 0 if trace_vsnapping then report_snapper("removed extra space at top: %p",extra) @@ -1326,16 +1325,16 @@ local function collapser(head,where,what,trace,snap,a_snapmethod) -- maybe also if trace then trace_done("flushed due to forced " .. why,glue_data) end - head = forced_skip(head,current,getfield(glue_data,"width") or 0,"before",trace) + head = forced_skip(head,current,getwidth(glue_data,width),"before",trace) flush_node(glue_data) else - local w = getfield(glue_data,"width") - if w ~= 0 then + local width, stretch, shrink = getglue(glue_data) + if width ~= 0 then if trace then trace_done("flushed due to non zero " .. why,glue_data) end head = insert_node_before(head,current,glue_data) - elseif getfield(glue_data,"stretch") ~= 0 or getfield(glue_data,"shrink") ~= 0 then + elseif stretch ~= 0 or shrink ~= 0 then if trace then trace_done("flushed due to stretch/shrink in" .. why,glue_data) end @@ -1398,16 +1397,15 @@ local function collapser(head,where,what,trace,snap,a_snapmethod) -- maybe also end else local h, d, ch, cd, lines, extra = snap_hlist("mvl",current,sv,false,false) -lastsnap = { - ht = h, - dp = d, - ch = ch, - cd = cd, - extra = extra, - current = current, -} -setprop(current,"snapper",lastsnap) - + lastsnap = { + ht = h, + dp = d, + ch = ch, + cd = cd, + extra = extra, + current = current, + } + setprop(current,"snapper",lastsnap) if trace_vsnapping then report_snapper("mvl %a snapped from (%p,%p) to (%p,%p) using method %a (%s) for %a (%s lines): %s", nodecodes[id],h,d,ch,cd,sv.name,sv.specification,where,lines,listtoutf(list)) @@ -1425,15 +1423,15 @@ setprop(current,"snapper",lastsnap) flush("list") current = getnext(current) elseif id == penalty_code then - -- natural_penalty = getfield(current,"penalty") + -- natural_penalty = getpenalty(current) -- if trace then -- trace_done("removed penalty",current) -- end -- head, current = remove_node(head, current, true) current = getnext(current) 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 getkern(current) ~= 0 then + report_snapper("kern of %p kept",getkern(current)) end flush("kern") current = getnext(current) @@ -1572,8 +1570,8 @@ setprop(current,"snapper",lastsnap) elseif glue_order == so then -- is now exclusive, maybe support goback as combi, else why a set if sc == largest then - local cw = getfield(current,"width") or 0 - local gw = getfield(glue_data,"width") or 0 + local cw = getwidth(current) + local gw = getwidth(glue_data) if cw > gw then if trace then trace_skip("largest",sc,so,sp,current) @@ -1636,7 +1634,7 @@ setprop(current,"snapper",lastsnap) local s = getattr(current,a_snapmethod) if s and s ~= 0 then setattr(current,a_snapmethod,0) - setfield(current,"width",0) + setwidth(current,0) if trace_vsnapping then report_snapper("lineskip set to zero") end @@ -1658,7 +1656,7 @@ setprop(current,"snapper",lastsnap) local s = getattr(current,a_snapmethod) if s and s ~= 0 then setattr(current,a_snapmethod,0) - setfield(current,"width",0) + setwidth(current,0) if trace_vsnapping then report_snapper("baselineskip set to zero") end @@ -1683,8 +1681,8 @@ setprop(current,"snapper",lastsnap) end head, current = remove_node(head, current, true) elseif glue_data then - local w = getfield(current,"width") or 0 - if ((w ~= 0) and (w > (getfield(glue_data,"width") or 0))) then + local w = getwidth(current) + if (w ~= 0) and (w > getwidth(glue_data)) then glue_data = current if trace then trace_natural("taking parskip",current) @@ -1763,7 +1761,7 @@ setprop(current,"snapper",lastsnap) -- else -- other glue if snap and trace_vsnapping then - local w = getfield(current,"width") or 0 + local w = getwidth(current) if w ~= 0 then report_snapper("glue %p of type %a kept",w,skipcodes[subtype]) end @@ -1795,7 +1793,7 @@ setprop(current,"snapper",lastsnap) if trace then trace_done("result",p) end - head, tail = insert_node_after(head,tail,p) + setlink(tail,p) -- if penalty_data > special_penalty_min and penalty_data < special_penalty_max then local props = properties[p] if props then @@ -1813,11 +1811,13 @@ setprop(current,"snapper",lastsnap) trace_done("result",glue_data) end if force_glue then - head, tail = forced_skip(head,tail,getfield(glue_data,"width") or 0,"after",trace) + head, tail = forced_skip(head,tail,getwidth(glue_data),"after",trace) flush_node(glue_data) glue_data = nil + elseif tail then + setlink(tail,glue_data) else - head, tail = insert_node_after(head,tail,glue_data) + head = glue_data end texnest[texnest.ptr].prevdepth = 0 -- appending to the list bypasses tex's prevdepth handler end @@ -1911,36 +1911,40 @@ function vspacing.pagehandler(newhead,where) return nil end -local ignore = table.tohash { - "split_keep", - "split_off", - -- "vbox", -} +do -function vspacing.vboxhandler(head,where) - if head and not ignore[where] then - local h = tonut(head) - if getnext(h) then -- what if a one liner and snapping? - h = collapser(h,"vbox",where,trace_vbox_vspacing,true,a_snapvbox) -- todo: local snapper - return tonode(h) + local ignore = table.tohash { + "split_keep", + "split_off", + -- "vbox", + } + + function vspacing.vboxhandler(head,where) + if head and not ignore[where] then + local h = tonut(head) + if getnext(h) then -- what if a one liner and snapping? + h = collapser(h,"vbox",where,trace_vbox_vspacing,true,a_snapvbox) -- todo: local snapper + return tonode(h) + end end + return head end - return head -end -function vspacing.collapsevbox(n,aslist) -- for boxes but using global a_snapmethod - local box = getbox(n) - if box then - local list = getlist(box) - if list then - list = collapser(list,"snapper","vbox",trace_vbox_vspacing,true,a_snapmethod) - if aslist then - setlist(box,list) -- beware, dimensions of box are wrong now - else - setlist(box,vpack_node(list)) + function vspacing.collapsevbox(n,aslist) -- for boxes but using global a_snapmethod + local box = getbox(n) + if box then + local list = getlist(box) + if list then + list = collapser(list,"snapper","vbox",trace_vbox_vspacing,true,a_snapmethod) + if aslist then + setlist(box,list) -- beware, dimensions of box are wrong now + else + setlist(box,vpack_node(list)) + end end end end + end -- This one is needed to prevent bleeding of prevdepth to the next page @@ -1979,71 +1983,75 @@ end -- interface -implement { - name = "vspacing", - actions = vspacing.analyze, - scope = "private", - arguments = "string" -} - -implement { - name = "resetprevdepth", - actions = vspacing.resetprevdepth, - scope = "private" -} - -implement { - name = "vspacingsetamount", - actions = vspacing.setskip, - scope = "private", - arguments = "string", -} - -implement { - name = "vspacingdefine", - actions = vspacing.setmap, - scope = "private", - arguments = { "string", "string" } -} - -implement { - name = "vspacingcollapse", - actions = vspacing.collapsevbox, - scope = "private", - arguments = "integer" -} - -implement { - name = "vspacingcollapseonly", - actions = vspacing.collapsevbox, - scope = "private", - arguments = { "integer", true } -} - -implement { - name = "vspacingsnap", - actions = vspacing.snapbox, - scope = "private", - arguments = { "integer", "integer" } -} - -implement { - name = "definesnapmethod", - actions = vspacing.definesnapmethod, - scope = "private", - arguments = { "string", "string" } -} - -local remove_node = nodes.remove -local find_node_tail = nodes.tail +do -interfaces.implement { - name = "fakenextstrutline", - actions = function() - local head = texlists.page_head - if head then - local head = remove_node(head,find_node_tail(head),true) - texlists.page_head = head + implement { + name = "vspacing", + actions = vspacing.analyze, + scope = "private", + arguments = "string" + } + + implement { + name = "resetprevdepth", + actions = vspacing.resetprevdepth, + scope = "private" + } + + implement { + name = "vspacingsetamount", + actions = vspacing.setskip, + scope = "private", + arguments = "string", + } + + implement { + name = "vspacingdefine", + actions = vspacing.setmap, + scope = "private", + arguments = { "string", "string" } + } + + implement { + name = "vspacingcollapse", + actions = vspacing.collapsevbox, + scope = "private", + arguments = "integer" + } + + implement { + name = "vspacingcollapseonly", + actions = vspacing.collapsevbox, + scope = "private", + arguments = { "integer", true } + } + + implement { + name = "vspacingsnap", + actions = vspacing.snapbox, + scope = "private", + arguments = { "integer", "integer" } + } + + implement { + name = "definesnapmethod", + actions = vspacing.definesnapmethod, + scope = "private", + arguments = { "string", "string" } + } + + local remove_node = nodes.remove + local find_node_tail = nodes.tail + + interfaces.implement { + name = "fakenextstrutline", + actions = function() + local head = texlists.page_head + if head then + local head = remove_node(head,find_node_tail(head),true) + texlists.page_head = head + end end - end -} + } + +end |