summaryrefslogtreecommitdiff
path: root/tex/context/base/mkxl/typo-lbx.lmt
diff options
context:
space:
mode:
Diffstat (limited to 'tex/context/base/mkxl/typo-lbx.lmt')
-rw-r--r--tex/context/base/mkxl/typo-lbx.lmt237
1 files changed, 151 insertions, 86 deletions
diff --git a/tex/context/base/mkxl/typo-lbx.lmt b/tex/context/base/mkxl/typo-lbx.lmt
index 00ba1cc7f..758f3c700 100644
--- a/tex/context/base/mkxl/typo-lbx.lmt
+++ b/tex/context/base/mkxl/typo-lbx.lmt
@@ -7,53 +7,67 @@ if not modules then modules = { } end modules ['typo-lbx'] = {
license = "see context related readme files"
}
+local context = context
+
local tostring = tostring
-local nuts = nodes.nuts
+local nuts = nodes.nuts
+local tonut = nodes.tonut
+local tonode = nodes.tonode
-local left_box_code = nodes.listcodes.left
-local right_box_code = nodes.listcodes.right
-local hlist_code = nodes.nodecodes.hlist
+local left_box_code = nodes.listcodes.left
+local right_box_code = nodes.listcodes.right
+local local_box_code = nodes.listcodes["local"]
+local hlist_code = nodes.nodecodes.hlist
-local getlist = nuts.getlist
-local getprev = nuts.getprev
-local getnext = nuts.getnext
-local getattribute = nuts.getattribute
-local gettail = nuts.tail
-local getwidth = nuts.getwidth
-local setlist = nuts.setlist
-local setoffsets = nuts.setoffsets
-local flushlist = nuts.flushlist
-local takebox = nuts.takebox
-local setbox = nuts.setbox
-local copynode = nuts.copynode
-local rangedimensions = nuts.rangedimensions
-local traverse_list = nuts.traversers.list
+-- some can go:
-local expandmacro = token.expandmacro
+local getlist = nuts.getlist
+local getprev = nuts.getprev
+local getnext = nuts.getnext
+local getattribute = nuts.getattribute
+local gettail = nuts.tail
+local getwidth = nuts.getwidth
+local getboth = nuts.getboth
+local getindex = nuts.getindex
+local setlist = nuts.setlist
+local flushlist = nuts.flushlist
+local takebox = nuts.takebox
+local setbox = nuts.setbox
+local copynode = nuts.copynode
+local rangedimensions = nuts.rangedimensions
+local traverse_list = nuts.traversers.list
-local dimension_value = tokens.values.dimension
-local integer_value = tokens.values.integer
+----- setlocalbox = tex.setlocalbox -- todo: also in node.direct namespace
+----- getlocalbox = tex.getlocalbox -- todo: also in node.direct namespace
-local implement = interfaces.implement
+local expandmacro = token.expandmacro
-typesetters = typesetters or { }
-local typesetters = typesetters
+local dimension_value = tokens.values.dimension
+local integer_value = tokens.values.integer
-typesetters.localboxes = typesetters.localboxes or { }
-local localboxes = typesetters.localboxes
+local implement = interfaces.implement
-local a_localboxes = attributes.private("localboxes")
+typesetters = typesetters or { }
+local typesetters = typesetters
-local starttiming = statistics.starttiming
-local stoptiming = statistics.stoptiming
+typesetters.localboxes = typesetters.localboxes or { }
+local localboxes = typesetters.localboxes
-do
+local a_localboxesmark = attributes.private("localboxesmark")
+
+local starttiming = statistics.starttiming
+local stoptiming = statistics.stoptiming
- local lb_attribute = 0
+do
+ local lb_found = nil
+ local lb_class = 0
local lb_linenumber = 0
- local lb_width = 0
- local lb_offset = 0
+ local lb_linewidth = 0
+ local lb_localwidth = 0
+ local lb_progress = 0
+ local lb_leftoffset = 0
+ local lb_rightoffset = 0
local lb_leftskip = 0
local lb_rightskip = 0
local lb_lefthang = 0
@@ -63,10 +77,13 @@ do
local lb_parfillrightskip = 0
local lb_overshoot = 0
- implement { name = "localboxattribute", public = true, usage = "value", actions = function() return integer_value, lb_attribute end }
+ implement { name = "localboxclass", public = true, usage = "value", actions = function() return integer_value, lb_class end }
implement { name = "localboxlinenumber", public = true, usage = "value", actions = function() return integer_value, lb_linenumber end }
- implement { name = "localboxwidth", public = true, usage = "value", actions = function() return dimension_value, lb_width end }
- implement { name = "localboxoffset", public = true, usage = "value", actions = function() return dimension_value, lb_offset end }
+ implement { name = "localboxlinewidth", public = true, usage = "value", actions = function() return dimension_value, lb_linewidth end }
+ implement { name = "localboxlocalwidth", public = true, usage = "value", actions = function() return dimension_value, lb_localwidth end }
+ implement { name = "localboxprogress", public = true, usage = "value", actions = function() return dimension_value, lb_progress end }
+ implement { name = "localboxleftoffset", public = true, usage = "value", actions = function() return dimension_value, lb_leftoffset end }
+ implement { name = "localboxrightoffset", public = true, usage = "value", actions = function() return dimension_value, lb_rightoffset end }
implement { name = "localboxleftskip", public = true, usage = "value", actions = function() return dimension_value, lb_leftskip end }
implement { name = "localboxrightskip", public = true, usage = "value", actions = function() return dimension_value, lb_rightskip end }
implement { name = "localboxlefthang", public = true, usage = "value", actions = function() return dimension_value, lb_lefthang end }
@@ -76,71 +93,115 @@ do
implement { name = "localboxparfillrightskip", public = true, usage = "value", actions = function() return dimension_value, lb_parfillrightskip end }
implement { name = "localboxovershoot", public = true, usage = "value", actions = function() return dimension_value, lb_overshoot end }
- local function action(current,where)
- -- We can have nested leftboxes!
- local l = getlist(current)
- setlist(current)
- local h = copynode(current)
- setlist(h,l)
- setbox("localboxcontentbox",h)
- expandmacro("localboxcommand") -- no longer pass arguments
- local b = takebox("localboxcontentbox")
- setlist(current,b)
- if where == "left" then
- local w = getwidth(b)
- setoffsets(b,lb_width - lb_offset - w)
- else
- setoffsets(b,lb_offset - lb_width)
+ local cache = table.setmetatableindex(function(t,k)
+ local v = { n = 0, m = 0 }
+ t[k] = v
+ return v
+ end)
+
+ -- todo: use a simple usernode that refers to a cache so that we don't need to
+ -- make copies
+
+ implement {
+ name = "localboxmarkonce",
+ public = true,
+ arguments = "integer",
+ actions = function(attr)
+ local c = cache[attr]
+ local n = c.n
+-- first test this:
+-- if n == c.m then
+-- print("all false",attr,n)
+-- -- all false
+-- n = 1
+-- c.m = 0
+-- else
+ n = n + 1
+-- end
+ c[n] = true
+ c.n = n
+ context(n)
+ end
+ }
+
+ local function action(current)
+ local list = getlist(current)
+ if list then
+ local attr = getattribute(list,a_localboxesmark) or 0
+ local cach = attr and cache[lb_class]
+ local once = cach and cach[attr]
+ if once == false then
+ setlist(current)
+ flushlist(list)
+ else
+ setlist(current)
+ local head = copynode(current)
+ setlist(head,list)
+ setbox("localboxcontentbox",head)
+ expandmacro("localboxcommand") -- no longer pass arguments
+ local box = takebox("localboxcontentbox")
+ setlist(current,box)
+ if once and cach[attr] == true then
+ cach[attr] = false
+ cach.m = cach.m + 1
+ end
+ end
end
end
- local function processleftbox(box,width)
+ -- these two are now more or less the same so ...
+
+ local function processleftbox(box)
local list = getlist(box)
- if not width then
- width = 0
- end
for current, id, subtype in traverse_list, list do
- if id == hlist_code then
- local a = getattribute(current,a_localboxes)
- if a then
- lb_attribute = a
- lb_width = width + rangedimensions(box,list,getprev(current))
- action(current,"left")
- end
- if subtype == left_box_code then
- processleftbox(current,width + rangedimensions(box,list,getprev(current)))
+ if subtype == local_box_code and getwidth(current) == 0 then
+ local class = getindex(current)
+ if class then
+ lb_found = current
+ lb_class = class
+ lb_progress = rangedimensions(box,list,current)
+ action(current)
end
end
end
end
- local function processrightbox(box,width)
+ local function processrightbox(box)
local list = getlist(box)
- local tail = gettail(list)
- if not width then
- width = 0
- end
for current, id, subtype in traverse_list, list do
- if id == hlist_code then
- local a = getattribute(current,a_localboxes)
- if a then
- lb_attribute = a
- lb_width = width + rangedimensions(box,list,getnext(current),tail)
- action(current,"right")
+ if subtype == local_box_code and getwidth(current) == 0 then
+ local class = getindex(current)
+ if class then
+ lb_found = current
+ lb_class = class
+ lb_progress = rangedimensions(box,list,current)
+ action(current)
end
- if subtype == right_box_code then
- processrightbox(current,width + rangedimensions(box,getnext(current),tail))
+ end
+ end
+ end
+
+ local function processmiddlebox(box,line)
+ local list = getlist(box)
+ for current, id, subtype in traverse_list, list do
+ if subtype == local_box_code and getwidth(current) == 0 then
+ local class = getindex(current)
+ if class then
+ lb_found = current
+ lb_class = class
+ lb_progress = rangedimensions(line,getlist(line),box)
+ action(current)
end
end
end
end
- local function processlocalboxes(line, leftbox, rightbox, linenumber, leftskip, rightskip, lefthang, righthang, indent, parfillleftskip, parfillrightskip, overshoot)
+ local function processlocalboxes(line,leftbox,rightbox,middlebox,linenumber,leftskip,rightskip,lefthang,righthang,indent,parfillleftskip,parfillrightskip,overshoot)
--
- lb_attribute = 0
+ lb_found = nil
+ lb_class = 0
lb_linenumber = linenumber
- lb_width = 0
- -- lb_offset = 0
+ lb_progress = 0
lb_leftskip = leftskip
lb_rightskip = rightskip
lb_lefthang = lefthang
@@ -149,15 +210,19 @@ do
lb_parfillleftskip = parfillleftskip
lb_parfillrightskip = parfillrightskip
lb_overshoot = overshoot
- --
- -- for now we always anchor
- --
+ lb_linewidth = getwidth(line)
+ lb_leftoffset = leftskip + lefthang + parfillleftskip + indent
+ lb_rightoffset = rightskip + righthang + parfillrightskip - overshoot
if leftbox then
- lb_offset = leftskip + lefthang + indent + parfillleftskip + getwidth(leftbox)
+ lb_localwidth = getwidth(leftbox)
processleftbox(leftbox)
end
+ if middlebox then
+ lb_localwidth = getwidth(middlebox)
+ processmiddlebox(middlebox,line)
+ end
if rightbox then
- lb_offset = rightskip + righthang + parfillrightskip + getwidth(rightbox) - overshoot
+ lb_localwidth = getwidth(rightbox)
processrightbox(rightbox)
end
end