summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/context/base/mkxl/pack-rul.lmt
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/tex/context/base/mkxl/pack-rul.lmt')
-rw-r--r--Master/texmf-dist/tex/context/base/mkxl/pack-rul.lmt258
1 files changed, 258 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/context/base/mkxl/pack-rul.lmt b/Master/texmf-dist/tex/context/base/mkxl/pack-rul.lmt
new file mode 100644
index 00000000000..d99f0a78e2c
--- /dev/null
+++ b/Master/texmf-dist/tex/context/base/mkxl/pack-rul.lmt
@@ -0,0 +1,258 @@
+if not modules then modules = { } end modules ['pack-rul'] = {
+ version = 1.001,
+ optimize = true,
+ 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
+
+-- \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 context = context
+
+local nodecodes = nodes.nodecodes
+local listcodes = nodes.listcodes
+
+local hlist_code = nodecodes.hlist
+local vlist_code = nodecodes.vlist
+
+local boxlist_code = listcodes.box
+local linelist_code = listcodes.line
+local equationlist_code = listcodes.equation
+
+local texsetdimen = tex.setdimen
+local texsetcount = tex.setcount
+
+local implement = interfaces.implement
+
+local nuts = nodes.nuts
+
+local getnext = nuts.getnext
+local getprev = nuts.getprev
+local getlist = nuts.getlist
+local setlist = nuts.setlist
+local getwhd = nuts.getwhd
+local getid = nuts.getid
+local getsubtype = nuts.getsubtype
+local getbox = nuts.getbox
+local getdirection = nuts.getdirection
+local setshift = nuts.setshift
+local setwidth = nuts.setwidth
+local getwidth = nuts.getwidth
+local setboxglue = nuts.setboxglue
+local getboxglue = nuts.getboxglue
+
+local hpack = nuts.hpack
+local getdimensions = nuts.dimensions
+local naturalhsize = nuts.naturalhsize
+local flush_node = nuts.flush
+
+local traversers = nuts.traversers
+local nexthlist = traversers.hlist
+local nextvlist = traversers.vlist
+local nextlist = traversers.list
+
+local checkformath = false
+
+directives.register("framed.checkmath",function(v) checkformath = v end) -- experiment
+
+-- beware: dir nodes and pseudostruts can end up on lines of their own
+
+local function doreshapeframedbox(n)
+ local box = getbox(n)
+ local noflines = 0
+ local nofnonzero = 0
+ local firstheight = nil
+ local lastdepth = nil
+ local lastlinelength = 0
+ local minwidth = 0
+ local maxwidth = 0
+ local totalwidth = 0
+ local averagewidth = 0
+ local boxwidth = getwidth(box)
+ -- if boxwidth ~= 0 and getsubtype(box) == vlist_code then
+ if boxwidth ~= 0 then
+ local list = getlist(box)
+ if list then
+ local hdone = false
+ for n, id, subtype, list in nextlist, list do -- no dir etc needed
+ local width, height, depth = getwhd(n)
+ if not firstheight then
+ firstheight = height
+ end
+ lastdepth = depth
+ noflines = noflines + 1
+ if list then
+ if id == hlist_code then
+ if subtype == boxlist_code or subtype == linelist_code then
+ -- the fast one also returns compensation (plus node)
+ local w, c, n = naturalhsize(list)
+ if n then
+ -- can become an option in framed: strict
+ w = w - c
+ else
+ -- print("no compensation found")
+ end
+ lastlinelength = w
+ else
+ lastlinelength = width
+ end
+ hdone = true
+ else
+ lastlinelength = width
+ -- vdone = true
+ end
+ if lastlinelength > maxwidth then
+ maxwidth = lastlinelength
+ end
+ if lastlinelength < minwidth or minwidth == 0 then
+ minwidth = lastlinelength
+ end
+ if lastlinelength > 0 then
+ nofnonzero = nofnonzero + 1
+ end
+ totalwidth = totalwidth + lastlinelength
+ end
+ end
+ if not firstheight then
+ -- done)
+ elseif maxwidth ~= 0 then
+ if hdone then
+ for h, id, subtype, list in nextlist, list do
+ if list and id == hlist_code then
+ -- called a lot so maybe a simple case is needed
+ if subtype == boxlist_code or subtype == linelist_code then
+ -- getdirection is irrelevant here so it will go
+ -- somehow a parfillskip also can get influenced
+ local p = hpack(list,maxwidth,'exactly',getdirection(h)) -- multiple return value
+ local set, order, sign = getboxglue(p)
+ setboxglue(h,set,order,sign)
+ setlist(p)
+ flush_node(p)
+ elseif checkformath and subtype == equationlist_code then
+ -- display formulas use a shift
+ if nofnonzero == 1 then
+ setshift(h,0)
+ end
+ end
+ setwidth(h,maxwidth)
+ end
+ end
+ end
+ -- if vdone then
+ -- for v in nextvlist, list do
+ -- local width = getwidth(n)
+ -- if width > maxwidth then
+ -- setwidth(v,maxwidth)
+ -- end
+ -- end
+ -- end
+ setwidth(box,maxwidth)
+ averagewidth = noflines > 0 and totalwidth/noflines or 0
+ else -- e.g. empty math {$ $} or \hbox{} or ...
+ setwidth(box,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) -- traverse_list
+ local box = getbox(n)
+ local noflines = 0
+ local firstheight = nil
+ local lastdepth = nil
+ if getwidth(box) ~= 0 then
+ local list = getlist(box)
+ if list then
+ for n in nexthlist, list do
+ local width, height, depth = getwhd(n)
+ if not firstheight then
+ firstheight = height
+ end
+ lastdepth = depth
+ noflines = noflines + 1
+ end
+ for n in nextvlist, list do
+ local width, height, depth = getwhd(n)
+ if not firstheight then
+ firstheight = height
+ end
+ lastdepth = depth
+ noflines = noflines + 1
+ 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 = getwidth(box)
+ 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
+ for n, subtype in nexthlist, list do -- no dir etc needed
+ local l = getlist(n)
+ if l then
+ if subtype == boxlist_code or subtype == linelist_code then
+ lastlinelength = getdimensions(l)
+ else
+ lastlinelength = getwidth(n)
+ end
+ if lastlinelength > maxwidth then
+ maxwidth = lastlinelength
+ end
+ end
+ end
+ for n, subtype in nextvlist, list do -- no dir etc needed
+ local l = getlist(n)
+ if l then
+ lastlinelength = getwidth(n)
+ if lastlinelength > maxwidth then
+ maxwidth = lastlinelength
+ end
+ end
+ end
+ return maxwidth
+end
+
+nodes.maxboxwidth = maxboxwidth
+
+implement {
+ name = "themaxboxwidth",
+ public = true,
+ actions = function(n) context("%rsp",maxboxwidth(getbox(n))) end, -- r = rounded
+ arguments = "integer"
+}