diff options
author | Marius <mariausol@gmail.com> | 2010-07-04 15:32:09 +0300 |
---|---|---|
committer | Marius <mariausol@gmail.com> | 2010-07-04 15:32:09 +0300 |
commit | 85b7bc695629926641c7cb752fd478adfdf374f3 (patch) | |
tree | 80293f5aaa7b95a500a78392c39688d8ee7a32fc /tex/context/base/node-ser.lua | |
download | context-85b7bc695629926641c7cb752fd478adfdf374f3.tar.gz |
stable 2010-05-24 13:10
Diffstat (limited to 'tex/context/base/node-ser.lua')
-rw-r--r-- | tex/context/base/node-ser.lua | 276 |
1 files changed, 276 insertions, 0 deletions
diff --git a/tex/context/base/node-ser.lua b/tex/context/base/node-ser.lua new file mode 100644 index 000000000..e632e92da --- /dev/null +++ b/tex/context/base/node-ser.lua @@ -0,0 +1,276 @@ +if not modules then modules = { } end modules ['node-ser'] = { + 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" +} + +-- beware, some field names will change in a next releases +-- of luatex; this is pretty old code that needs an overhaul + +local type, format, concat = type, string.format, table.concat + +local ctxcatcodes = tex.ctxcatcodes + +local hlist = node.id('hlist') +local vlist = node.id('vlist') + +local traverse = node.traverse +local node_fields = node.fields +local node_type = node.type + +local expand = table.tohash { + "list", -- list_ptr & ins_ptr & adjust_ptr + "pre", -- + "post", -- + "spec", -- glue_ptr + "top_skip", -- + "attr", -- + "replace", -- nobreak + "components", -- lig_ptr + "box_left", -- + "box_right", -- + "glyph", -- margin_char + "leader", -- leader_ptr + "action", -- action_ptr + "value", -- user_defined nodes with subtype 'a' en 'n' +} + +-- page_insert: "height", "last_ins_ptr", "best_ins_ptr" +-- split_insert: "height", "last_ins_ptr", "best_ins_ptr", "broken_ptr", "broken_ins" + +local ignore = table.tohash { + "page_insert", + "split_insert", + "ref_count", +} + +local dimension = table.tohash { + "width", "height", "depth", "shift", + "stretch", "shrink", + "xoffset", "yoffset", + "surround", + "kern", + "box_left_width", "box_right_width" +} + +-- flat: don't use next, but indexes +-- verbose: also add type +-- can be sped up + +nodes.dimensionfields = dimension +nodes.listablefields = expand +nodes.ignorablefields = ignore + +-- not ok yet: + +function nodes.astable(n,sparse) -- not yet ok + local f, t = node_fields(n.id,n.subtype), { } + for i=1,#f do + local v = f[i] + local d = n[v] + if d then + if ignore[v] or v == "id" then + -- skip + elseif expand[v] then -- or: type(n[v]) ~= "string" or type(n[v]) ~= "number" or type(n[v]) ~= "table" + t[v] = "pointer to list" + elseif sparse then + if (type(d) == "number" and d ~= 0) or (type(d) == "string" and d ~= "") then + t[v] = d + end + else + t[v] = d + end + end + end + t.type = node_type(n.id) + return t +end + +-- under construction: + +local function totable(n,flat,verbose) + -- todo: no local function + local function to_table(n,flat,verbose) + local f = node_fields(n.id,n.subtype) + local tt = { } + for k=1,#f do + local v = f[k] + local nv = n[v] + if nv then + if ignore[v] then + -- skip + elseif expand[v] then + if type(nv) == "number" or type(nv) == "string" then + tt[v] = nv + else + tt[v] = totable(nv,flat,verbose) + end + elseif type(nv) == "table" then + tt[v] = nv -- totable(nv,flat,verbose) -- data + else + tt[v] = nv + end + end + end + if verbose then + tt.type = node_type(tt.id) + end + return tt + end + if n then + if flat then + local t = { } + while n do + t[#t+1] = to_table(n,flat,verbise) + n = n.next + end + return t + else + local t = to_table(n) + if n.next then + t.next = totable(n.next,flat,verbose) + end + return t + end + else + return { } + end +end + +nodes.totable = totable + +local function key(k) + return ((type(k) == "number") and "["..k.."]") or k +end + +-- not ok yet; this will become a module + +local function serialize(root,name,handle,depth,m) + handle = handle or print + if depth then + depth = depth .. " " + handle(format("%s%s={",depth,key(name))) + else + depth = "" + local tname = type(name) + if tname == "string" then + if name == "return" then + handle("return {") + else + handle(name .. "={") + end + elseif tname == "number" then + handle("[" .. name .. "]={") + else + handle("t={") + end + end + if root then + local fld + if root.id then + fld = node_fields(root.id,root.subtype) -- we can cache these (todo) + else + fld = table.sortedkeys(root) + end + if type(root) == 'table' and root['type'] then -- userdata or table + handle(format("%s %s=%q,",depth,'type',root['type'])) + end + for f=1,#fld do + local k = fld[f] + if k == "ref_count" then + -- skip + elseif k then + local v = root[k] + local t = type(v) + if t == "number" then + if v == 0 then + -- skip + else + handle(format("%s %s=%s,",depth,key(k),v)) + end + elseif t == "string" then + if v == "" then + -- skip + else + handle(format("%s %s=%q,",depth,key(k),v)) + end + elseif t == "boolean" then + handle(format("%s %s=%q,",depth,key(k),tostring(v))) + elseif v then -- userdata or table + serialize(v,k,handle,depth,m+1) + end + end + end + if root['next'] then -- userdata or table + serialize(root['next'],'next',handle,depth,m+1) + end + end + if m and m > 0 then + handle(format("%s},",depth)) + else + handle(format("%s}",depth)) + end +end + +function nodes.serialize(root,name) + local t = { } + local function flush(s) + t[#t+1] = s + end + serialize(root, name, flush, nil, 0) + return concat(t,"\n") +end + +function nodes.serializebox(n,flat,verbose,name) + return nodes.serialize(nodes.totable(tex.box[n],flat,verbose),name) +end + +function nodes.visualizebox(...) + tex.print(ctxcatcodes,"\\starttyping") + tex.print(nodes.serializebox(...)) + tex.print("\\stoptyping") +end + +function nodes.list(head,n) -- name might change to nodes.type + if not n then + tex.print(ctxcatcodes,"\\starttyping") + end + while head do + local id = head.id + tex.print(string.rep(" ",n or 0) .. tostring(head) .. "\n") + if id == hlist or id == vlist then + nodes.list(head.list,(n or 0)+1) + end + head = head.next + end + if not n then + tex.print("\\stoptyping") + end +end + +function nodes.print(head,n) + while head do + local id = head.id + texio.write_nl(string.rep(" ",n or 0) .. tostring(head)) + if id == hlist or id == vlist then + nodes.print(head.list,(n or 0)+1) + end + head = head.next + end +end + +function nodes.check_for_leaks(sparse) + local l = { } + local q = node.usedlist() + for p in traverse(q) do + local s = table.serialize(nodes.astable(p,sparse),node_type(p.id)) + l[s] = (l[s] or 0) + 1 + end + node.flush_list(q) + for k, v in next, l do + texio.write_nl(format("%s * %s", v, k)) + end +end + |