diff options
Diffstat (limited to 'Master/texmf-dist/tex/context/base/mkxl/node-aux.lmt')
-rw-r--r-- | Master/texmf-dist/tex/context/base/mkxl/node-aux.lmt | 396 |
1 files changed, 396 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/context/base/mkxl/node-aux.lmt b/Master/texmf-dist/tex/context/base/mkxl/node-aux.lmt new file mode 100644 index 00000000000..d952ec41b51 --- /dev/null +++ b/Master/texmf-dist/tex/context/base/mkxl/node-aux.lmt @@ -0,0 +1,396 @@ +if not modules then modules = { } end modules ['node-aux'] = { + version = 1.001, + comment = "companion to node-ini.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +-- todo: n1 .. n2 : __concat metatable + +local type, tostring = type, tostring + +local nodes = nodes +local context = context + +local utfvalues = utf.values + +local nodecodes = nodes.nodecodes + +local glyph_code = nodecodes.glyph +local hlist_code = nodecodes.hlist +local vlist_code = nodecodes.vlist +local attributelist_code = nodecodes.attributelist -- temporary +local par_code = nodecodes.par + +local nuts = nodes.nuts +local tonut = nuts.tonut +local tonode = nuts.tonode +local vianuts = nuts.vianuts + +local getbox = nuts.getbox +local getnext = nuts.getnext +local getid = nuts.getid +local getsubtype = nuts.getsubtype +local getlist = nuts.getlist +local getattr = nuts.getattr +local getboth = nuts.getboth +local getprev = nuts.getprev +local getwidth = nuts.getwidth +local setwidth = nuts.setwidth +local getboxglue = nuts.getboxglue +local setboxglue = nuts.setboxglue + +local setfield = nuts.setfield +local setattr = nuts.setattr +local setlink = nuts.setlink +local setlist = nuts.setlist +local setnext = nuts.setnext +local setprev = nuts.setprev +local setattrlist = nuts.setattrlist + +local traversers = nuts.traversers +local nextnode = traversers.node +local nextglyph = traversers.glyph + +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 find_tail = nuts.tail +local getbox = nuts.getbox +local count = nuts.count +local isglyph = nuts.isglyph + +local nodepool = nuts.pool +local new_glue = nodepool.glue +local new_glyph = nodepool.glyph + +local unsetvalue = attributes.unsetvalue + +local current_font = font.current + +local texsetbox = tex.setbox + +local report_error = logs.reporter("node-aux:error") + +local function takebox(id) + local box = getbox(id) + if box then + local list = getlist(box) + setlist(box,nil) + local copy = copy_node(box) + if list then + setlist(copy,list) + end + texsetbox(id,false) + return copy + end +end + +function nodes.takebox(id) + local b = takebox(id) + if b then + return tonode(b) + end +end + +local splitbox = tex.splitbox +nodes.splitbox = splitbox + +function nuts.splitbox(id,height) + return tonut(splitbox(id,height)) +end + +-- function nodes.takelist(n) +-- -- when we need it +-- end + +function nuts.takelist(n) + local l = getlist(n) + setlist(n) + flush_node(n) + return l +end + +nuts.takebox = takebox +tex.takebox = nodes.takebox -- sometimes more clear + +-- so far + +local function repackhlist(list,...) + local temp, b = hpack_nodes(list,...) + list = getlist(temp) + setlist(temp) + flush_node(temp) + return list, b +end + +nuts.repackhlist = repackhlist + +function nodes.repackhlist(list,...) + local list, b = repackhlist(tonut(list),...) + return tonode(list), b +end + +local function set_attributes(head,attr,value) + for n, id in nextnode, head do + setattr(n,attr,value) + if id == hlist_node or id == vlist_node then + set_attributes(getlist(n),attr,value) + end + end +end + +local function set_unset_attributes(head,attr,value) + for n, id in nextnode, head do + if not getattr(n,attr) then + setattr(n,attr,value) + end + if id == hlist_code or id == vlist_code then + set_unset_attributes(getlist(n),attr,value) + end + end +end + +local function unset_attributes(head,attr) + for n, id in nextnode, head do + setattr(n,attr,unsetvalue) + if id == hlist_code or id == vlist_code then + unset_attributes(getlist(n),attr) + end + end +end + +-- for old times sake + +nuts.setattribute = nuts.setattr nodes.setattribute = nodes.setattr +nuts.getattribute = nuts.getattr nodes.getattribute = nodes.getattr +nuts.unsetattribute = nuts.unset_attribute nodes.unsetattribute = nodes.unset_attribute +nuts.has_attribute = nuts.has_attribute nodes.has_attribute = nodes.has_attribute +nuts.firstglyph = nuts.first_glyph nodes.firstglyph = nodes.first_glyph + +nuts.setattributes = set_attributes nodes.setattributes = vianuts(set_attributes) +nuts.setunsetattributes = set_unset_attributes nodes.setunsetattributes = vianuts(set_unset_attributes) +nuts.unsetattributes = unset_attributes nodes.unsetattributes = vianuts(unset_attributes) + +function nuts.firstcharacter(n,untagged) -- tagged == subtype > 255 + if untagged then + return first_glyph(n) + else + for g in nextglyph ,n do + return g + end + end +end + +local function firstcharinbox(n) + local l = getlist(getbox(n)) + if l then + for g, c in nextglyph, l do + return c + end + end + return 0 +end + +nuts .firstcharinbox = firstcharinbox +nodes.firstcharinbox = firstcharinbox -- hm, ok ? +nodes.firstcharacter = vianuts(firstcharacter) + +interfaces.implement { + name = "buildtextaccent", + arguments = "integer", + actions = function(n) -- Is this crap really used? Or was it an experiment? + local char = firstcharinbox(n) + if char > 0 then + -- context.accent(false,char) + context([[\accent%s\relax]],char) + end + end +} + +-- this depends on fonts, so we have a funny dependency ... will be +-- sorted out .. we could make tonodes a plugin into this + +local function tonodes(str,fnt,attr) -- (str,template_glyph) -- moved from blob-ini + if not str or str == "" then + return + end + local head, tail, space, fnt, template = nil, nil, nil, nil, nil + if not fnt then + fnt = current_font() + elseif type(fnt) ~= "number" and getid(fnt) == glyph_code then -- so it has to be a real node + fnt, template = nil, tonut(fnt) + end + for s in utfvalues(str) do + local n + if s == 32 then + if space then + n = copy_node(space) + elseif fonts then -- depedency + local parameters = fonts.hashes.identifiers[fnt].parameters + space = new_glue(parameters.space,parameters.space_stretch,parameters.space_shrink) + n = space + end + elseif template then + n = copy_node(template) + setvalue(n,"char",s) + else + n = new_glyph(fnt,s) + end + if attr then -- normally false when template + setattrlist(n,attr) + end + if head then + setlink(tail,n) + else + head = n + end + tail = n + end + return head, tail +end + +nuts.tonodes = tonodes + +nodes.tonodes = function(str,fnt,attr) + local head, tail = tonodes(str,fnt,attr) + return tonode(head), tonode(tail) +end + +local function link(list,currentfont,currentattr,head,tail) -- an oldie, might be replaced + for i=1,#list do + local n = list[i] + if n then + local tn = type(n) + if 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 + setnext(tail,h) + setprev(h,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 + 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 + setlink(tail,n) + if getnext(n) then + tail = find_tail(n) + else + tail = n + end + end + else + -- permitting nil is convenient + end + end + return head, tail +end + +nuts.link = link + +nodes.link = function(list,currentfont,currentattr,head,tail) + local head, tail = link(list,currentfont,currentattr,tonut(head),tonut(tail)) + return tonode(head), tonode(tail) +end + +local function locate(start,wantedid,wantedsubtype) + for n, id, subtype in nextnode, start do + if id == wantedid then + if not wantedsubtype or subtype == wantedsubtype then + return n + end + elseif id == hlist_code or id == vlist_code then + local found = locate(getlist(n),wantedid,wantedsubtype) + if found then + return found + end + end + end +end + +nuts.locate = locate + +function nodes.locate(start,wantedid,wantedsubtype) + local found = locate(tonut(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) + local set, order, sign = getboxglue(temp) + setboxglue(n,set,order,sign) + setlist(temp) + flush_node(temp) + return n +end + +nuts.rehpack = rehpack + +function nodes.rehpack(n,...) + rehpack(tonut(n),...) +end + +do + + local parcodes = nodes.parcodes + local hmodepar_code = parcodes.hmode_par + local vmodepar_code = parcodes.vmode_par + + local getnest = tex.getnest + local getsubtype = nuts.getsubtype + + function nuts.setparproperty(action,...) + local tail = tonut(getnest().tail) + while tail do + if getid(tail) == par_code then + local s = getsubtype(tail) + if s == hmodepar_code or s == vmodepar_code then + return action(tail,...) + else + -- something is wrong here + end + end + tail = getprev(tail) + end + end + + local getsubtype = nodes.getsubtype + + function nodes.start_of_par(n) + local s = getsubtype(n) + return s == hmodepar_code or s == vmodepar_code + end + +end |