summaryrefslogtreecommitdiff
path: root/tex/context/base/mkiv/node-aux.lua
diff options
context:
space:
mode:
Diffstat (limited to 'tex/context/base/mkiv/node-aux.lua')
-rw-r--r--tex/context/base/mkiv/node-aux.lua319
1 files changed, 210 insertions, 109 deletions
diff --git a/tex/context/base/mkiv/node-aux.lua b/tex/context/base/mkiv/node-aux.lua
index ebe113fc6..c6b276337 100644
--- a/tex/context/base/mkiv/node-aux.lua
+++ b/tex/context/base/mkiv/node-aux.lua
@@ -20,7 +20,6 @@ local glyph_code = nodecodes.glyph
local hlist_code = nodecodes.hlist
local vlist_code = nodecodes.vlist
local attributelist_code = nodecodes.attributelist -- temporary
-local math_code = nodecodes.math
local nuts = nodes.nuts
local tonut = nuts.tonut
@@ -36,6 +35,10 @@ local getfont = nuts.getfont
local getchar = nuts.getchar
local getattr = nuts.getattr
local getfield = nuts.getfield
+local getboth = nuts.getboth
+local getcomponents = nuts.getcomponents
+local getwidth = nuts.getwidth
+local setwidth = nuts.setwidth
local setfield = nuts.setfield
local setattr = nuts.setattr
@@ -43,22 +46,21 @@ local setlink = nuts.setlink
local setlist = nuts.setlist
local setnext = nuts.setnext
local setprev = nuts.setprev
+local setcomponents = nuts.setcomponents
+local setattrlist = nuts.setattrlist
local traverse_nodes = nuts.traverse
local traverse_id = nuts.traverse_id
-local free_node = nuts.free
+local flush_node = nuts.flush
+local flush_list = nuts.flush_list
local hpack_nodes = nuts.hpack
local unset_attribute = nuts.unset_attribute
local first_glyph = nuts.first_glyph
local copy_node = nuts.copy
-local copy_node_list = nuts.copy_list
+----- copy_node_list = nuts.copy_list
local find_tail = nuts.tail
-local insert_node_after = nuts.insert_after
-local isnode = nuts.is_node
local getbox = nuts.getbox
-
-local nodes_traverse_id = nodes.traverse_id
-local nodes_first_glyph = nodes.first_glyph
+local count = nuts.count
local nodepool = nuts.pool
local new_glue = nodepool.glue
@@ -93,13 +95,13 @@ local report_error = logs.reporter("node-aux:error")
local function takebox(id)
local box = getbox(id)
if box then
- local copy = copy_node(box)
local list = getlist(box)
+ setlist(box,nil)
+ local copy = copy_node(box)
if list then
setlist(copy,list)
- setlist(box,nil)
end
- texsetbox(id,nil)
+ texsetbox(id,false)
return copy
end
end
@@ -125,7 +127,7 @@ end
function nuts.takelist(n)
local l = getlist(n)
setlist(n)
- free_node(n)
+ flush_node(n)
return l
end
@@ -138,7 +140,7 @@ local function repackhlist(list,...)
local temp, b = hpack_nodes(list,...)
list = getlist(temp)
setlist(temp)
- free_node(temp)
+ flush_node(temp)
return list, b
end
@@ -262,16 +264,6 @@ nuts.unsetattributes = unset_attributes nodes.unsetattribut
-- end
-- end
--
--- if not node.end_of_math then
--- function node.end_of_math(n)
--- for n in traverse_id(math_code,getnext(next)) do
--- return n
--- end
--- end
--- end
---
--- nodes.endofmath = node.end_of_math
---
-- local function firstline(n)
-- while n do
-- local id = getid(n)
@@ -300,16 +292,6 @@ function nuts.firstcharacter(n,untagged) -- tagged == subtype > 255
end
end
--- function nodes.firstcharacter(n,untagged) -- tagged == subtype > 255
--- if untagged then
--- return nodes_first_glyph(n)
--- else
--- for g in nodes_traverse_id(glyph_code,n) do
--- return g
--- end
--- end
--- end
-
local function firstcharinbox(n)
local l = getlist(getbox(n))
if l then
@@ -366,11 +348,10 @@ local function tonodes(str,fnt,attr) -- (str,template_glyph) -- moved from blob-
n = new_glyph(fnt,s)
end
if attr then -- normally false when template
- -- setfield(n,"attr",copy_node_list(attr))
- setfield(n,"attr",attr)
+ setattrlist(n,attr)
end
if head then
- insert_node_after(head,tail,n)
+ setlink(tail,n)
else
head = n
end
@@ -386,79 +367,6 @@ nodes.tonodes = function(str,fnt,attr)
return tonode(head), tonode(tail)
end
--- local function link(list,currentfont,currentattr,head,tail)
--- for i=1,#list do
--- local n = list[i]
--- if n then
--- local tn = isnode(n)
--- if not tn then
--- local tn = type(n)
--- if tn == "number" then
--- if not currentfont then
--- currentfont = current_font()
--- end
--- local h, t = tonodes(tostring(n),currentfont,currentattr)
--- if not h then
--- -- skip
--- elseif not head then
--- head = h
--- tail = t
--- else
--- setfield(tail,"next",h)
--- setfield(h,"prev",t)
--- tail = t
--- end
--- elseif tn == "string" then
--- if #tn > 0 then
--- if not currentfont then
--- currentfont = current_font()
--- end
--- local h, t = tonodes(n,currentfont,currentattr)
--- if not h then
--- -- skip
--- elseif not head then
--- head, tail = h, t
--- else
--- setfield(tail,"next",h)
--- setfield(h,"prev",t)
--- tail = t
--- end
--- end
--- elseif tn == "table" then
--- if #tn > 0 then
--- if not currentfont then
--- currentfont = current_font()
--- end
--- head, tail = link(n,currentfont,currentattr,head,tail)
--- end
--- end
--- elseif not head then
--- head = n
--- tail = find_tail(n)
--- elseif getid(n) == attributelist_code then
--- -- weird case
--- report_error("weird node type in list at index %s:",i)
--- for i=1,#list do
--- local l = list[i]
--- report_error("%3i: %s %S",i,getid(l) == attributelist_code and "!" or ">",l)
--- end
--- os.exit()
--- else
--- setfield(tail,"next",n)
--- setfield(n,"prev",tail)
--- if getnext(n) then
--- tail = find_tail(n)
--- else
--- tail = n
--- end
--- end
--- else
--- -- permitting nil is convenient
--- end
--- end
--- return head, tail
--- end
-
local function link(list,currentfont,currentattr,head,tail) -- an oldie, might be replaced
for i=1,#list do
local n = list[i]
@@ -543,6 +451,25 @@ function nodes.locate(start,wantedid,wantedsubtype)
return found and tonode(found)
end
+local function rehpack(n,width)
+ local head = getlist(n)
+ local size = width or getwidth(n)
+ local temp = hpack_nodes(head,size,"exactly")
+ setwidth(n,size)
+ setfield(n,"glue_set", getfield(temp,"glue_set"))
+ setfield(n,"glue_sign", getfield(temp,"glue_sign"))
+ setfield(n,"glue_order",getfield(temp,"glue_order"))
+ setlist(temp)
+ flush_node(temp)
+ return n
+end
+
+nuts.rehpack = rehpack
+
+function nodes.rehpack(n,...)
+ rehpack(tonut(n),...)
+end
+
-- I have no use for this yet:
--
-- \skip0=10pt plus 2pt minus 2pt
@@ -561,3 +488,177 @@ end
-- return 0
-- end
-- end
+
+-- these component helpers might move to another module
+
+-- nodemode helper: here we also flatten components, no check for disc here
+
+function nuts.set_components(target,start,stop)
+ local head = getcomponents(target)
+ if head then
+ flush_list(head)
+ head = nil
+ end
+ if start then
+ setprev(start)
+ else
+ return nil
+ end
+ if stop then
+ setnext(stop)
+ end
+ local tail = nil
+ while start do
+ local c = getcomponents(start)
+ local n = getnext(start)
+ if c then
+ if head then
+ setlink(tail,c)
+ else
+ head = c
+ end
+ tail = find_tail(c)
+ setcomponents(start)
+ flush_node(start)
+ else
+ if head then
+ setlink(tail,start)
+ else
+ head = start
+ end
+ tail = start
+ end
+ start = n
+ end
+ setcomponents(target,head)
+ -- maybe also upgrade the subtype but we don't use it anyway
+ return head
+end
+
+function nuts.get_components(target)
+ return getcomponents(target)
+end
+
+nuts.get_components = getcomponents
+
+function nuts.take_components(target)
+ local c = getcomponents(target)
+ setcomponents(target)
+ -- maybe also upgrade the subtype but we don't use it anyway
+ return c
+end
+
+-- nodemode helper: we assume a glyph and a flat components list (basemode can
+-- have nested components)
+
+function nuts.count_components(n,marks)
+ local components = getcomponents(n)
+ if components then
+ if marks then
+ local i = 0
+ for g in traverse_id(glyph_code,components) do
+ if not marks[getchar(g)] then
+ i = i + 1
+ end
+ end
+ return i
+ else
+ return count(glyph_code,components)
+ end
+ else
+ return 0
+ end
+end
+
+-- nodemode helper: the next and prev pointers are untouched
+
+function nuts.copy_no_components(g,copyinjection)
+ local components = getcomponents(g)
+ if components then
+ setcomponents(g)
+ local n = copy_node(g)
+ if copyinjection then
+ copyinjection(n,g)
+ end
+ setcomponents(g,components)
+ -- maybe also upgrade the subtype but we don't use it anyway
+ return n
+ else
+ local n = copy_node(g)
+ if copyinjection then
+ copyinjection(n,g)
+ end
+ return n
+ end
+end
+
+function nuts.copy_only_glyphs(current)
+ local head = nil
+ local previous = nil
+ for n in traverse_id(glyph_code,current) do
+ n = copy_node(n)
+ if head then
+ setlink(previous,n)
+ else
+ head = n
+ end
+ previous = n
+ end
+ return head
+end
+
+-- node- and basemode helper
+
+function nuts.use_components(head,current)
+ local components = getcomponents(current)
+ if not components then
+ return head, current, current
+ end
+ local prev, next = getboth(current)
+ local first = current
+ local last = next
+ while components do
+ local gone = current
+ local tail = find_tail(components)
+ if prev then
+ setlink(prev,components)
+ end
+ if next then
+ setlink(tail,next)
+ end
+ if first == current then
+ first = components
+ end
+ if head == current then
+ head = components
+ end
+ current = components
+ setcomponents(gone)
+ flush_node(gone)
+ while true do
+ components = getcomponents(current)
+ if components then
+ next = getnext(current)
+ break -- current is composed
+ end
+ if next == last then
+ last = current
+ break -- components is false
+ end
+ prev = current
+ current = next
+ next = getnext(current)
+ end
+ end
+ return head, first, last
+end
+
+-- function nuts.current_tail()
+-- local whatever = texnest[texnest.ptr]
+-- if whatever then
+-- local tail = whatever.tail
+-- if tail then
+-- return tonut(tail)
+-- end
+-- end
+-- end