summaryrefslogtreecommitdiff
path: root/tex/context/base/mkiv/spac-ver.lua
diff options
context:
space:
mode:
authorHans Hagen <pragma@wxs.nl>2017-02-17 10:31:56 +0100
committerContext Git Mirror Bot <phg42.2a@gmail.com>2017-02-17 10:31:56 +0100
commitb14f992ef5f4e868c9959b174278c86516d60dbc (patch)
tree28587bb46c025ea7b0d27ba93f09c93dcf53c73a /tex/context/base/mkiv/spac-ver.lua
parent95a1799032dc61dbca4a11e495be34b4397c8fec (diff)
downloadcontext-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.lua342
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