diff options
author | Karl Berry <karl@freefriends.org> | 2016-04-22 22:14:39 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2016-04-22 22:14:39 +0000 |
commit | fc4466b32ed330a956ac603b00fd145524cff49a (patch) | |
tree | 2c50e2b8de13aa9233b2c76dffe201558f169e86 /Master/texmf-dist/tex/context/base/mkiv/pack-rul.lua | |
parent | 50e2368597d5f6fe2057195d0ae6a9f2044923e4 (diff) |
context (22apr16)
git-svn-id: svn://tug.org/texlive/trunk@40691 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/context/base/mkiv/pack-rul.lua')
-rw-r--r-- | Master/texmf-dist/tex/context/base/mkiv/pack-rul.lua | 231 |
1 files changed, 231 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/context/base/mkiv/pack-rul.lua b/Master/texmf-dist/tex/context/base/mkiv/pack-rul.lua new file mode 100644 index 00000000000..427a2d11da0 --- /dev/null +++ b/Master/texmf-dist/tex/context/base/mkiv/pack-rul.lua @@ -0,0 +1,231 @@ +if not modules then modules = { } end modules ['pack-rul'] = { + version = 1.001, + comment = "companion to pack-rul.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +--[[ldx-- +<p>An explanation is given in the history document <t>mk</t>.</p> +--ldx]]-- + +-- we need to be careful with display math as it uses shifts +-- challenge: adapt glue_set +-- setfield(h,"glue_set", getfield(h,"glue_set") * getfield(h,"width")/maxwidth -- interesting ... doesn't matter much + +-- \framed[align={lohi,middle}]{$x$} +-- \framed[align={lohi,middle}]{$ $} +-- \framed[align={lohi,middle}]{\hbox{ }} +-- \framed[align={lohi,middle}]{\hbox{}} +-- \framed[align={lohi,middle}]{$\hskip2pt$} + +local type = type + +local hlist_code = nodes.nodecodes.hlist +local vlist_code = nodes.nodecodes.vlist +local box_code = nodes.listcodes.box +local line_code = nodes.listcodes.line + +local texsetdimen = tex.setdimen +local texsetcount = tex.setcount + +local implement = interfaces.implement + +local nuts = nodes.nuts + +local getfield = nuts.getfield +local setfield = nuts.setfield +local getnext = nuts.getnext +local getprev = nuts.getprev +local getlist = nuts.getlist +local setlist = nuts.setlist +local getid = nuts.getid +local getsubtype = nuts.getsubtype +local getbox = nuts.getbox + +local hpack = nuts.hpack +local traverse_id = nuts.traverse_id +local node_dimensions = nuts.dimensions +local free_node = nuts.free + +local function doreshapeframedbox(n) + local box = getbox(n) + local noflines = 0 + local firstheight = nil + local lastdepth = nil + local lastlinelength = 0 + local minwidth = 0 + local maxwidth = 0 + local totalwidth = 0 + local averagewidth = 0 + local boxwidth = getfield(box,"width") + if boxwidth ~= 0 then -- and h.subtype == vlist_code + local list = getlist(box) + if list then + local function check(n,repack) + if not firstheight then + firstheight = getfield(n,"height") + end + lastdepth = getfield(n,"depth") + noflines = noflines + 1 + local l = getlist(n) + if l then + if repack then + local subtype = getsubtype(n) + if subtype == box_code or subtype == line_code then + -- used to be: hpack(copy(l)).width + lastlinelength = node_dimensions(l,getfield(n,"dir")) + else + lastlinelength = getfield(n,"width") + end + else + lastlinelength = getfield(n,"width") + end + if lastlinelength > maxwidth then + maxwidth = lastlinelength + end + if lastlinelength < minwidth or minwidth == 0 then + minwidth = lastlinelength + end + totalwidth = totalwidth + lastlinelength + end + end + local hdone = false + for h in traverse_id(hlist_code,list) do -- no dir etc needed + check(h,true) + hdone = true + end + -- local vdone = false + for v in traverse_id(vlist_code,list) do -- no dir etc needed + check(v,false) + -- vdone = true + end + if not firstheight then + -- done) + elseif maxwidth ~= 0 then + if hdone then + for h in traverse_id(hlist_code,list) do + local l = getlist(h) + if l then + local subtype = getsubtype(h) + if subtype == box_code or subtype == line_code then + local p = hpack(l,maxwidth,'exactly',getfield(h,"dir")) -- multiple return value + if false then + setlist(h,p) + setfield(h,"shift",0) -- needed for display math, so no width check possible + -- setfield(p,"attr",getfield(h,"attr")) + else + setfield(h,"glue_set",getfield(p,"glue_set")) + setfield(h,"glue_order",getfield(p,"glue_order")) + setfield(h,"glue_sign",getfield(p,"glue_sign")) + setlist(p) + free_node(p) + end + end + setfield(h,"width",maxwidth) + end + end + end + -- if vdone then + -- for v in traverse_id(vlist_code,list) do + -- local width = getfield(n,"width") + -- if width > maxwidth then + -- setfield(v,"width",maxwidth) + -- end + -- end + -- end + setfield(box,"width",maxwidth) + averagewidth = noflines > 0 and totalwidth/noflines or 0 + else -- e.g. empty math {$ $} or \hbox{} or ... +setfield(box,"width",0) + end + end + end + texsetcount("global","framednoflines",noflines) + texsetdimen("global","framedfirstheight",firstheight or 0) -- also signal + texsetdimen("global","framedlastdepth",lastdepth or 0) + texsetdimen("global","framedminwidth",minwidth) + texsetdimen("global","framedmaxwidth",maxwidth) + texsetdimen("global","framedaveragewidth",averagewidth) +end + +local function doanalyzeframedbox(n) + local box = getbox(n) + local noflines = 0 + local firstheight = nil + local lastdepth = nil + if getfield(box,"width") ~= 0 then + local list = getlist(box) + if list then + local function check(n) + if not firstheight then + firstheight = getfield(n,"height") + end + lastdepth = getfield(n,"depth") + noflines = noflines + 1 + end + for h in traverse_id(hlist_code,list) do + check(h) + end + for v in traverse_id(vlist_code,list) do + check(v) + end + end + end + texsetcount("global","framednoflines",noflines) + texsetdimen("global","framedfirstheight",firstheight or 0) + texsetdimen("global","framedlastdepth",lastdepth or 0) +end + +implement { name = "doreshapeframedbox", actions = doreshapeframedbox, arguments = "integer" } +implement { name = "doanalyzeframedbox", actions = doanalyzeframedbox, arguments = "integer" } + +local function maxboxwidth(box) + local boxwidth = getfield(box,"width") + if boxwidth == 0 then + return 0 + end + local list = getlist(box) + if not list then + return 0 + end + if getid(box) == hlist_code then + return boxwidth + end + local lastlinelength = 0 + local maxwidth = 0 + local function check(n,repack) + local l = getlist(n) + if l then + if repack then + local subtype = getsubtype(n) + if subtype == box_code or subtype == line_code then + lastlinelength = node_dimensions(l,getfield(n,"dir")) + else + lastlinelength = getfield(n,"width") + end + else + lastlinelength = getfield(n,"width") + end + if lastlinelength > maxwidth then + maxwidth = lastlinelength + end + end + end + for h in traverse_id(hlist_code,list) do -- no dir etc needed + check(h,true) + end + for v in traverse_id(vlist_code,list) do -- no dir etc needed + check(v,false) + end + return maxwidth +end + +nodes.maxboxwidth = maxboxwidth + +implement { + name = "themaxboxwidth", + actions = function(n) context("%isp",maxboxwidth(getbox(n))) end, + arguments = "integer" +} |