diff options
Diffstat (limited to 'Master/texmf-dist/tex/context/base/mkiv/node-rul.lua')
-rw-r--r-- | Master/texmf-dist/tex/context/base/mkiv/node-rul.lua | 374 |
1 files changed, 153 insertions, 221 deletions
diff --git a/Master/texmf-dist/tex/context/base/mkiv/node-rul.lua b/Master/texmf-dist/tex/context/base/mkiv/node-rul.lua index ea0e5c7a0c8..2b0368c2bc5 100644 --- a/Master/texmf-dist/tex/context/base/mkiv/node-rul.lua +++ b/Master/texmf-dist/tex/context/base/mkiv/node-rul.lua @@ -37,20 +37,18 @@ local setlink = nuts.setlink local getnext = nuts.getnext local getprev = nuts.getprev local getid = nuts.getid -local getdirection = nuts.getdirection +local getdir = nuts.getdir local getattr = nuts.getattr local setattr = nuts.setattr local getfont = nuts.getfont local getsubtype = nuts.getsubtype local getlist = nuts.getlist local setwhd = nuts.setwhd +local setdir = nuts.setdir local setattrlist = nuts.setattrlist local setshift = nuts.setshift local getwidth = nuts.getwidth local setwidth = nuts.setwidth -local setfield = nuts.setfield - -local isglyph = nuts.isglyph local flushlist = nuts.flush_list local effective_glue = nuts.effective_glue @@ -58,16 +56,17 @@ local insert_node_after = nuts.insert_after local insert_node_before = nuts.insert_before local find_tail = nuts.tail local setglue = nuts.setglue -local getrangedimensions = nuts.rangedimensions +local traverse_id = nuts.traverse_id +local list_dimensions = nuts.rangedimensions local hpack_nodes = nuts.hpack +local current_attr = nuts.current_attr local copy_list = nuts.copy_list -local nexthlist = nuts.traversers.hlist - local nodecodes = nodes.nodecodes local rulecodes = nodes.rulecodes local gluecodes = nodes.gluecodes local listcodes = nodes.listcodes +local kerncodes = nodes.kerncodes local glyph_code = nodecodes.glyph local localpar_code = nodecodes.localpar @@ -75,8 +74,8 @@ local dir_code = nodecodes.dir local glue_code = nodecodes.glue local hlist_code = nodecodes.hlist -local indentlist_code = listcodes.indent -local linelist_code = listcodes.line +local indent_code = listcodes.indent +local line_code = listcodes.line local leftskip_code = gluecodes.leftskip local rightskip_code = gluecodes.rightskip @@ -122,8 +121,8 @@ local setmetatableindex = table.setmetatableindex -- -local striprange = nuts.striprange -local processwords = nuts.processwords +local striprange = nodes.striprange +local processwords = nodes.processwords -- @@ -145,7 +144,7 @@ local function usernutrule(t,noattributes) if noattributes == false or noattributes == nil then -- avoid fuzzy ones else - setattrlist(r,true) + setattrlist(r,current_attr()) end properties[r] = t return r @@ -157,11 +156,9 @@ local function userrule(t,noattributes) return tonode(usernutrule(t,noattributes)) end -rules.userrule = userrule -local ruleactions = { } - -rules .ruleactions = ruleactions -nutrules.ruleactions = ruleactions -- convenient +rules.userrule = userrule +local ruleactions = { } +rules.ruleactions = ruleactions local function mathradical(n,h,v) ----- size = getfield(n,"index") @@ -206,18 +203,18 @@ local subtypeactions = { [rulecodes.radical] = mathradical, } -local function process_rule(n,h,v) - local n = tonut(n) - local s = getsubtype(n) - local a = subtypeactions[s] - if a then - a(n,h,v) - end -end - -callbacks.register("process_rule",process_rule,"handle additional user rule features") - -callbacks.functions.process_rule = process_rule +callbacks.register( + "process_rule", + function(n,h,v) + local n = tonut(n) + local s = getsubtype(n) + local a = subtypeactions[s] + if a then + a(n,h,v) + end + end, + "handle additional user rule features" +) -- @@ -242,9 +239,9 @@ end local function flush_ruled(head,f,l,d,level,parent,strip) -- not that fast but acceptable for this purpose local font = nil - local char, id = isglyph(f) - if char then - font = id + local id = getid(f) + if id == glyph_code then + font = getfont(f) elseif id == hlist_code then font = getattr(f,a_runningtext) end @@ -266,7 +263,7 @@ local function flush_ruled(head,f,l,d,level,parent,strip) -- not that fast but a if not f then return head end - local w, ht, dp = getrangedimensions(parent,f,getnext(l)) + local w, ht, dp = list_dimensions(parent,f,getnext(l)) local method = d.method local empty = d.empty == v_yes local offset = d.offset @@ -334,7 +331,7 @@ local function flush_ruled(head,f,l,d,level,parent,strip) -- not that fast but a end end if mp and mp ~= "" then - local r = usernutrule { + local r = userrule { width = w, height = ht, depth = dp, @@ -347,17 +344,16 @@ local function flush_ruled(head,f,l,d,level,parent,strip) -- not that fast but a ca = color, ta = transparency, } - inject(r,w,ht,dp) + inject(tonut(r),w,ht,dp) else local tx = d.text if tx then - local l = copy_list(tx) + tx = copy_list(tx) if d["repeat"] == v_yes then - l = new_leader(w,l) - setattrlist(l,tx) + tx = new_leader(w,tx) end - l = hpack_nodes(l,w,"exactly") - inject(l,w,ht,dp) + local r = hpack_nodes(tx,w,"exactly") + inject(r,w,ht,dp) else for i=1,level do local ht = (offset+(i-1)*dy)*e + rulethickness - m @@ -377,8 +373,10 @@ local function flush_ruled(head,f,l,d,level,parent,strip) -- not that fast but a return head end +local process = nodes.processwords + rules.handler = function(head) - return processwords(a_ruled,data,flush_ruled,head) + return process(a_ruled,data,flush_ruled,head) end function rules.enable() @@ -411,7 +409,7 @@ local function flush_shifted(head,first,last,data,level,parent,strip) -- not tha local next = getnext(last) setprev(first) setnext(last) - local width, height, depth = getrangedimensions(parent,first,next) + local width, height, depth = list_dimensions(parent,first,next) local list = hpack_nodes(first,width,"exactly") -- we can use a simple pack if first == head then head = list @@ -431,9 +429,9 @@ local function flush_shifted(head,first,last,data,level,parent,strip) -- not tha return head end -nodes.shifts.handler = function(head) - return processwords(a_shifted,data,flush_shifted,head) -end +local process = nodes.processwords + +nodes.shifts.handler = function(head) return process(a_shifted,data,flush_shifted,head) end function nodes.shifts.enable() enableaction("shipouts","nodes.shifts.handler") @@ -461,7 +459,7 @@ local function linefiller(current,data,width,location) local ca = data.ca local ta = data.ta if mp and mp ~= "" then - return usernutrule { + return tonut(userrule { width = width, height = height, depth = depth, @@ -472,56 +470,18 @@ local function linefiller(current,data,width,location) ca = ca, ta = ta, option = location, - direction = getdirection(current), - } + direction = getdir(current), + }) else - local rule = new_rule(width,height,depth) + local linefiller = new_rule(width,height,depth) if ca then - setattr(rule,a_colorspace,ma) - setattr(rule,a_color,ca) + setattr(linefiller,a_colorspace,ma) + setattr(linefiller,a_color,ca) end if ta then - setattr(rule,a_transparency,ta) - end - return rule - end -end - -function nodes.linefillers.filler(current,data,width,height,depth) - if width and width > 0 then - local height = height or data.height or 0 - local depth = depth or data.depth or 0 - if (height + depth) ~= 0 then - local mp = data.mp - local ma = data.ma - local ca = data.ca - local ta = data.ta - if mp and mp ~= "" then - return usernutrule { - width = width, - height = height, - depth = depth, - type = "mp", - line = data.rulethickness, - data = mp, - ma = ma, - ca = ca, - ta = ta, - option = location, - direction = getdirection(current), - } - else - local rule = new_rule(width,height,depth) - if ca then - setattr(rule,a_colorspace,ma) - setattr(rule,a_color,ca) - end - if ta then - setattr(rule,a_transparency,ta) - end - return rule - end + setattr(linefiller,a_transparency,ta) end + return linefiller end end @@ -536,115 +496,119 @@ local function find_attr(head,attr) end function nodes.linefillers.handler(head) - for current, subtype, list in nexthlist, head do - if list and subtype == linelist_code then - -- why doesn't leftskip take the attributes - -- or list[linefiller] or maybe first match (maybe we need a fast helper for that) - local a = getattr(current,a_linefiller) - if a then - local class = a % 1000 - local data = data[class] - if data then - local location = data.location - local scope = data.scope - local distance = data.distance - local threshold = data.threshold - local leftlocal = false - local rightlocal = false - -- - if scope == v_right then - leftlocal = true - elseif scope == v_left then - rightlocal = true - elseif scope == v_local then - leftlocal = true - rightlocal = true - end - -- - if location == v_left or location == v_both then - local lskip = nil -- leftskip - local iskip = nil -- indentation - local head = list - while head do - local id = getid(head) - if id == glue_code then - if getsubtype(head) == leftskip_code then - lskip = head +-- local current = tonut(head) -- when we hook into the contributers + for current in traverse_id(hlist_code,tonut(head)) do + if getsubtype(current) == line_code then + local list = getlist(current) + if list then + -- why doesn't leftskip take the attributes + -- or list[linefiller] or maybe first match (maybe we need a fast helper for that) + local a = getattr(current,a_linefiller) + if a then + local class = a % 1000 + local data = data[class] + if data then + local location = data.location + local scope = data.scope + local distance = data.distance + local threshold = data.threshold + local leftlocal = false + local rightlocal = false + -- + if scope == v_right then + leftlocal = true + elseif scope == v_left then + rightlocal = true + elseif scope == v_local then + leftlocal = true + rightlocal = true + end + -- + if location == v_left or location == v_both then + local lskip = nil -- leftskip + local iskip = nil -- indentation + local head = list + while head do + local id = getid(head) + if id == glue_code then + if getsubtype(head) == leftskip_code then + lskip = head + else + break + end + elseif id == localpar_code or id == dir_code then + -- go on + elseif id == hlist_code then + if getsubtype(head) == indent_code then + iskip = head + end + break else break end - elseif id == localpar_code or id == dir_code then - -- go on - elseif id == hlist_code then - if getsubtype(head) == indentlist_code then - iskip = head - end - break - else - break + head = getnext(head) end - head = getnext(head) - end - if head then - local indentation = iskip and getwidth(iskip) or 0 - local leftfixed = lskip and getwidth(lskip) or 0 - local lefttotal = lskip and effective_glue(lskip,current) or 0 - local width = lefttotal - (leftlocal and leftfixed or 0) + indentation - distance - if width > threshold then - if iskip then - setwidth(iskip,0) - end - if lskip then - setglue(lskip,leftlocal and getwidth(lskip) or nil) - if distance > 0 then - insert_node_after(list,lskip,new_kern(distance)) + if head then + local indentation = iskip and getwidth(iskip) or 0 + local leftfixed = lskip and getwidth(lskip) or 0 + local lefttotal = lskip and effective_glue(lskip,current) or 0 + local width = lefttotal - (leftlocal and leftfixed or 0) + indentation - distance + if width > threshold then + if iskip then + setwidth(iskip,0) end - insert_node_after(list,lskip,linefiller(current,data,width,"left")) - else - insert_node_before(list,head,linefiller(current,data,width,"left")) - if distance > 0 then - insert_node_before(list,head,new_kern(distance)) + if lskip then + setglue(lskip,leftlocal and getwidth(lskip) or nil) + if distance > 0 then + insert_node_after(list,lskip,new_kern(distance)) + end + insert_node_after(list,lskip,linefiller(current,data,width,"left")) + else + insert_node_before(list,head,linefiller(current,data,width,"left")) + if distance > 0 then + insert_node_before(list,head,new_kern(distance)) + end end end end end - end - -- - if location == v_right or location == v_both then - local pskip = nil -- parfillskip - local rskip = nil -- rightskip - local tail = find_tail(list) - while tail and getid(tail) == glue_code do - local subtype = getsubtype(tail) - if subtype == rightskip_code then - rskip = tail - elseif subtype == parfillskip_code then - pskip = tail - else - break - end - tail = getprev(tail) - end - if tail then - local rightfixed = rskip and getwidth(rskip) or 0 - local righttotal = rskip and effective_glue(rskip,current) or 0 - local parfixed = pskip and getwidth(pskip) or 0 - local partotal = pskip and effective_glue(pskip,current) or 0 - local width = righttotal - (rightlocal and rightfixed or 0) + partotal - distance - if width > threshold then - if pskip then - setglue(pskip) + -- + if location == v_right or location == v_both then + local pskip = nil -- parfillskip + local rskip = nil -- rightskip + local tail = find_tail(list) + while tail and getid(tail) == glue_code do + local subtype = getsubtype(tail) + if subtype == rightskip_code then + rskip = tail + elseif subtype == parfillskip_code then + pskip = tail + else + break end - if rskip then - setglue(rskip,rightlocal and getwidth(rskip) or nil) - if distance > 0 then - insert_node_before(list,rskip,new_kern(distance)) + tail = getprev(tail) + end + if tail then + local rightfixed = rskip and getwidth(rskip) or 0 + local righttotal = rskip and effective_glue(rskip,current) or 0 + local parfixed = pskip and getwidth(pskip) or 0 + local partotal = pskip and effective_glue(pskip,current) or 0 + local width = righttotal - (rightlocal and rightfixed or 0) + partotal - distance + if width > threshold then + if pskip then + setglue(pskip) end - insert_node_before(list,rskip,linefiller(current,data,width,"right")) - else - insert_node_after(list,tail,linefiller(current,data,width,"right")) - if distance > 0 then - insert_node_after(list,tail,new_kern(distance)) + if rskip then + setglue(rskip,rightlocal and getwidth(rskip) or nil) + if distance > 0 then + insert_node_before(list,rskip,new_kern(distance)) + end + insert_node_before(list,rskip,linefiller(current,data,width,"right")) + else + insert_node_after(list,tail,linefiller(current,data,width,"right")) + if distance > 0 then + insert_node_after(list,tail,new_kern(distance)) + end end end end @@ -744,35 +708,3 @@ implement { onlyonce = true, actions = nodes.linefillers.enable } - --- We add a bonus feature here: - -interfaces.implement { - name = "autorule", - arguments = { - { - { "width", "dimension" }, - { "height", "dimension" }, - { "depth", "dimension" }, - { "left", "dimension" }, - { "right", "dimension" }, - }, - }, - actions = function(t) - local l = t.left - local r = t.right - local n = new_rule( - t.width, - t.height, - t.depth - ) - setattrlist(n,true) - if l then - setfield(n,"left",l) - end - if r then - setfield(n,"right",r) - end - context(tonode(n)) - end -} |