diff options
author | Hans Hagen <pragma@wxs.nl> | 2013-05-20 02:00:00 +0200 |
---|---|---|
committer | Hans Hagen <pragma@wxs.nl> | 2013-05-20 02:00:00 +0200 |
commit | bd95a21d2b31a5fab1b4cc7c2b0334823fb3a3e9 (patch) | |
tree | 831128c411476f077eb7910d8c08f524d3ee43ec /tex/context/base/node-tra.lua | |
parent | 9a10021cd4cb23995ad3ffa915fc5b7f6890aaf8 (diff) | |
download | context-bd95a21d2b31a5fab1b4cc7c2b0334823fb3a3e9.tar.gz |
beta 2013.05.20 02:00
Diffstat (limited to 'tex/context/base/node-tra.lua')
-rw-r--r-- | tex/context/base/node-tra.lua | 1058 |
1 files changed, 529 insertions, 529 deletions
diff --git a/tex/context/base/node-tra.lua b/tex/context/base/node-tra.lua index f194239bb..916b2143d 100644 --- a/tex/context/base/node-tra.lua +++ b/tex/context/base/node-tra.lua @@ -1,529 +1,529 @@ -if not modules then modules = { } end modules ['node-tra'] = {
- 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"
-}
-
---[[ldx--
-<p>This is rather experimental. We need more control and some of this
-might become a runtime module instead. This module will be cleaned up!</p>
---ldx]]--
-
-local utfchar = utf.char
-local format, match, gmatch, concat, rep = string.format, string.match, string.gmatch, table.concat, string.rep
-local lpegmatch = lpeg.match
-local clock = os.gettimeofday or os.clock -- should go in environment
-
-local report_nodes = logs.reporter("nodes","tracing")
-
-nodes = nodes or { }
-
-local nodes, node, context = nodes, node, context
-
-local tracers = nodes.tracers or { }
-nodes.tracers = tracers
-
-local tasks = nodes.tasks or { }
-nodes.tasks = tasks
-
-local handlers = nodes.handlers or {}
-nodes.handlers = handlers
-
-local injections = nodes.injections or { }
-nodes.injections = injections
-
-local traverse_nodes = node.traverse
-local traverse_by_id = node.traverse_id
-local count_nodes = nodes.count
-
-local nodecodes = nodes.nodecodes
-local whatcodes = nodes.whatcodes
-local skipcodes = nodes.skipcodes
-local fillcodes = nodes.fillcodes
-
-local glyph_code = nodecodes.glyph
-local hlist_code = nodecodes.hlist
-local vlist_code = nodecodes.vlist
-local disc_code = nodecodes.disc
-local glue_code = nodecodes.glue
-local kern_code = nodecodes.kern
-local rule_code = nodecodes.rule
-local whatsit_code = nodecodes.whatsit
-local spec_code = nodecodes.glue_spec
-
-local localpar_code = whatcodes.localpar
-local dir_code = whatcodes.dir
-
-local nodepool = nodes.pool
-
-local dimenfactors = number.dimenfactors
-local formatters = string.formatters
-
--- this will be reorganized:
-
-function nodes.showlist(head, message)
- if message then
- report_nodes(message)
- end
- for n in traverse_nodes(head) do
- report_nodes(tostring(n))
- end
-end
-
-function nodes.handlers.checkglyphs(head,message)
- local t = { }
- for g in traverse_by_id(glyph_code,head) do
- t[#t+1] = formatters["%U:%s"](g.char,g.subtype)
- end
- if #t > 0 then
- if message and message ~= "" then
- report_nodes("%s, %s glyphs: % t",message,#t,t)
- else
- report_nodes("%s glyphs: % t",#t,t)
- end
- end
- return false
-end
-
-function nodes.handlers.checkforleaks(sparse)
- local l = { }
- local q = node.usedlist()
- for p in traverse(q) do
- local s = table.serialize(nodes.astable(p,sparse),nodecodes[p.id])
- l[s] = (l[s] or 0) + 1
- end
- node.flush_list(q)
- for k, v in next, l do
- write_nl(formatters["%s * %s"](v,k))
- end
-end
-
-local f_sequence = formatters["U+%04X:%s"]
-
-local function tosequence(start,stop,compact)
- if start then
- local t = { }
- while start do
- local id = start.id
- if id == glyph_code then
- local c = start.char
- if compact then
- if start.components then
- t[#t+1] = tosequence(start.components,nil,compact)
- else
- t[#t+1] = utfchar(c)
- end
- else
- t[#t+1] = f_sequence(c,utfchar(c))
- end
- elseif id == whatsit_code and start.subtype == localpar_code or start.subtype == dir_code then
- t[#t+1] = "[" .. start.dir .. "]"
- elseif id == rule_code then
- if compact then
- t[#t+1] = "|"
- else
- t[#t+1] = nodecodes[id]
- end
- else
- if compact then
- t[#t+1] = "[]"
- else
- t[#t+1] = nodecodes[id]
- end
- end
- if start == stop then
- break
- else
- start = start.next
- end
- end
- if compact then
- return concat(t)
- else
- return concat(t," ")
- end
- else
- return "[empty]"
- end
-end
-
-nodes.tosequence = tosequence
-
-function nodes.report(t,done)
- report_nodes("output %a, %changed %a, %s nodes",status.output_active,done,count_nodes(t))
-end
-
-function nodes.packlist(head)
- local t = { }
- for n in traverse(head) do
- t[#t+1] = tostring(n)
- end
- return t
-end
-
-function nodes.idstostring(head,tail)
- local t, last_id, last_n = { }, nil, 0
- for n in traverse_nodes(head,tail) do -- hm, does not stop at tail
- local id = n.id
- if not last_id then
- last_id, last_n = id, 1
- elseif last_id == id then
- last_n = last_n + 1
- else
- if last_n > 1 then
- t[#t+1] = formatters["[%s*%s]"](last_n,nodecodes[last_id] or "?")
- else
- t[#t+1] = formatters["[%s]"](nodecodes[last_id] or "?")
- end
- last_id, last_n = id, 1
- end
- if n == tail then
- break
- end
- end
- if not last_id then
- t[#t+1] = "no nodes"
- elseif last_n > 1 then
- t[#t+1] = formatters["[%s*%s]"](last_n,nodecodes[last_id] or "?")
- else
- t[#t+1] = formatters["[%s]"](nodecodes[last_id] or "?")
- end
- return concat(t," ")
-end
-
--- function nodes.xidstostring(head,tail) -- only for special tracing of backlinks
--- local n = head
--- while n.next do
--- n = n.next
--- end
--- local t, last_id, last_n = { }, nil, 0
--- while n do
--- local id = n.id
--- if not last_id then
--- last_id, last_n = id, 1
--- elseif last_id == id then
--- last_n = last_n + 1
--- else
--- if last_n > 1 then
--- t[#t+1] = formatters["[%s*%s]"](last_n,nodecodes[last_id] or "?")
--- else
--- t[#t+1] = formatters["[%s]"](nodecodes[last_id] or "?")
--- end
--- last_id, last_n = id, 1
--- end
--- if n == head then
--- break
--- end
--- n = n.prev
--- end
--- if not last_id then
--- t[#t+1] = "no nodes"
--- elseif last_n > 1 then
--- t[#t+1] = formatters["[%s*%s]"](last_n,nodecodes[last_id] or "?")
--- else
--- t[#t+1] = formatters["[%s]"](nodecodes[last_id] or "?")
--- end
--- return table.concat(table.reversed(t)," ")
--- end
-
-local function showsimplelist(h,depth,n)
- while h do
- write_nl(rep(" ",n) .. tostring(h))
- if not depth or n < depth then
- local id = h.id
- if id == hlist_code or id == vlist_code then
- showsimplelist(h.list,depth,n+1)
- end
- end
- h = h.next
- end
-end
-
---~ \startluacode
---~ callback.register('buildpage_filter',function() nodes.show_simple_list(tex.lists.contrib_head) end)
---~ \stopluacode
---~ \vbox{b\footnote{n}a}
---~ \startluacode
---~ callback.register('buildpage_filter',nil)
---~ \stopluacode
-
-nodes.showsimplelist = function(h,depth) showsimplelist(h,depth,0) end
-
-local function listtoutf(h,joiner,textonly,last)
- local joiner = (joiner == true and utfchar(0x200C)) or joiner -- zwnj
- local w = { }
- while h do
- local id = h.id
- if id == glyph_code then -- always true
- w[#w+1] = utfchar(h.char)
- if joiner then
- w[#w+1] = joiner
- end
- elseif id == disc_code then
- local pre, rep, pos = h.pre, h.replace, h.post
- w[#w+1] = formatters["[%s|%s|%s]"] (
- pre and listtoutf(pre,joiner,textonly) or "",
- rep and listtoutf(rep,joiner,textonly) or "",
- mid and listtoutf(mid,joiner,textonly) or ""
- )
- elseif textonly then
- if id == glue_code and h.spec and h.spec.width > 0 then
- w[#w+1] = " "
- end
- else
- w[#w+1] = "[-]"
- end
- if h == last then
- break
- else
- h = h.next
- end
- end
- return concat(w)
-end
-
-nodes.listtoutf = listtoutf
-
-local what = { [0] = "unknown", "line", "box", "indent", "row", "cell" }
-
-local function showboxes(n,symbol,depth)
- depth, symbol = depth or 0, symbol or "."
- for n in traverse_nodes(n) do
- local id = n.id
- if id == hlist_code or id == vlist_code then
- local s = n.subtype
- report_nodes(rep(symbol,depth) .. what[s] or s)
- showboxes(n.list,symbol,depth+1)
- end
- end
-end
-
-nodes.showboxes = showboxes
-
-local ptfactor = dimenfactors.pt
-local bpfactor = dimenfactors.bp
-local stripper = lpeg.patterns.stripzeros
-
--- start redefinition
---
--- -- if fmt then
--- -- return formatters[fmt](n*dimenfactors[unit],unit)
--- -- else
--- -- return match(formatters["%.20f"](n*dimenfactors[unit]),"(.-0?)0*$") .. unit
--- -- end
---
--- redefined:
-
-local dimenfactors = number.dimenfactors
-
-local function numbertodimen(d,unit,fmt,strip)
- if not d then
- local str = formatters[fmt](0,unit)
- return strip and lpegmatch(stripper,str) or str
- end
- local t = type(d)
- if t == 'string' then
- return d
- end
- if unit == true then
- unit = "pt"
- fmt = "%0.5f%s"
- else
- unit = unit or 'pt'
- if not fmt then
- fmt = "%s%s"
- elseif fmt == true then
- fmt = "%0.5f%s"
- end
- end
- if t == "number" then
- local str = formatters[fmt](d*dimenfactors[unit],unit)
- return strip and lpegmatch(stripper,str) or str
- end
- local id = node.id
- if id == kern_code then
- local str = formatters[fmt](d.width*dimenfactors[unit],unit)
- return strip and lpegmatch(stripper,str) or str
- end
- if id == glue_code then
- d = d.spec
- end
- if not d or not d.id == spec_code then
- local str = formatters[fmt](0,unit)
- return strip and lpegmatch(stripper,str) or str
- end
- local width = d.width
- local plus = d.stretch_order
- local minus = d.shrink_order
- local stretch = d.stretch
- local shrink = d.shrink
- if plus ~= 0 then
- plus = " plus " .. stretch/65536 .. fillcodes[plus]
- elseif stretch ~= 0 then
- plus = formatters[fmt](stretch*dimenfactors[unit],unit)
- plus = " plus " .. (strip and lpegmatch(stripper,plus) or plus)
- else
- plus = ""
- end
- if minus ~= 0 then
- minus = " minus " .. shrink/65536 .. fillcodes[minus]
- elseif shrink ~= 0 then
- minus = formatters[fmt](shrink*dimenfactors[unit],unit)
- minus = " minus " .. (strip and lpegmatch(stripper,minus) or minus)
- else
- minus = ""
- end
- local str = formatters[fmt](d.width*dimenfactors[unit],unit)
- return (strip and lpegmatch(stripper,str) or str) .. plus .. minus
-end
-
-number.todimen = numbertodimen
-
-function number.topoints (n,fmt) return numbertodimen(n,"pt",fmt) end
-function number.toinches (n,fmt) return numbertodimen(n,"in",fmt) end
-function number.tocentimeters (n,fmt) return numbertodimen(n,"cm",fmt) end
-function number.tomillimeters (n,fmt) return numbertodimen(n,"mm",fmt) end
-function number.toscaledpoints(n,fmt) return numbertodimen(n,"sp",fmt) end
-function number.toscaledpoints(n) return n .. "sp" end
-function number.tobasepoints (n,fmt) return numbertodimen(n,"bp",fmt) end
-function number.topicas (n,fmt) return numbertodimen(n "pc",fmt) end
-function number.todidots (n,fmt) return numbertodimen(n,"dd",fmt) end
-function number.tociceros (n,fmt) return numbertodimen(n,"cc",fmt) end
-function number.tonewdidots (n,fmt) return numbertodimen(n,"nd",fmt) end
-function number.tonewciceros (n,fmt) return numbertodimen(n,"nc",fmt) end
-
--- stop redefinition
-
-local points = function(n)
- if not n or n == 0 then
- return "0pt"
- elseif type(n) == "number" then
- return lpegmatch(stripper,format("%.5fpt",n*ptfactor)) -- faster than formatter
- else
- return numbertodimen(n,"pt",true,true) -- also deals with nodes
- end
-end
-
-local basepoints = function(n)
- if not n or n == 0 then
- return "0bp"
- elseif type(n) == "number" then
- return lpegmatch(stripper,format("%.5fbp",n*bpfactor)) -- faster than formatter
- else
- return numbertodimen(n,"bp",true,true) -- also deals with nodes
- end
-end
-
-local pts = function(n)
- if not n or n == 0 then
- return "0pt"
- elseif type(n) == "number" then
- return format("%.5fpt",n*ptfactor) -- faster than formatter
- else
- return numbertodimen(n,"pt",true) -- also deals with nodes
- end
-end
-
-local nopts = function(n)
- if not n or n == 0 then
- return "0"
- else
- return format("%.5f",n*ptfactor) -- faster than formatter
- end
-end
-
-number.points = points
-number.basepoints = basepoints
-number.pts = pts
-number.nopts = nopts
-
-local colors = { }
-tracers.colors = colors
-
-local unsetvalue = attributes.unsetvalue
-
-local a_color = attributes.private('color')
-local a_colormodel = attributes.private('colormodel')
-local m_color = attributes.list[a_color] or { }
-
-function colors.set(n,c,s)
- local mc = m_color[c]
- if not mc then
- n[a_color] = unsetvalue
- else
- if not n[a_colormodel] then
- n[a_colormodel] = s or 1
- end
- n[a_color] = mc
- end
- return n
-end
-
-function colors.setlist(n,c,s)
- local f = n
- while n do
- local mc = m_color[c]
- if not mc then
- n[a_color] = unsetvalue
- else
- if not n[a_colormodel] then
- n[a_colormodel] = s or 1
- end
- n[a_color] = mc
- end
- n = n.next
- end
- return f
-end
-
-function colors.reset(n)
- n[a_color] = unsetvalue
- return n
-end
-
--- maybe
-
-local transparencies = { }
-tracers.transparencies = transparencies
-
-local a_transparency = attributes.private('transparency')
-local m_transparency = attributes.list[a_transparency] or { }
-
-function transparencies.set(n,t)
- local mt = m_transparency[t]
- if not mt then
- n[a_transparency] = unsetvalue
- else
- n[a_transparency] = mt
- end
- return n
-end
-
-function transparencies.setlist(n,c,s)
- local f = n
- while n do
- local mt = m_transparency[c]
- if not mt then
- n[a_transparency] = unsetvalue
- else
- n[a_transparency] = mt
- end
- n = n.next
- end
- return f
-end
-
-function transparencies.reset(n)
- n[a_transparency] = unsetvalue
- return n
-end
-
--- for the moment here
-
-nodes.visualizers = { }
-
-function nodes.visualizers.handler(head)
- return head, false
-end
+if not modules then modules = { } end modules ['node-tra'] = { + 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" +} + +--[[ldx-- +<p>This is rather experimental. We need more control and some of this +might become a runtime module instead. This module will be cleaned up!</p> +--ldx]]-- + +local utfchar = utf.char +local format, match, gmatch, concat, rep = string.format, string.match, string.gmatch, table.concat, string.rep +local lpegmatch = lpeg.match +local clock = os.gettimeofday or os.clock -- should go in environment + +local report_nodes = logs.reporter("nodes","tracing") + +nodes = nodes or { } + +local nodes, node, context = nodes, node, context + +local tracers = nodes.tracers or { } +nodes.tracers = tracers + +local tasks = nodes.tasks or { } +nodes.tasks = tasks + +local handlers = nodes.handlers or {} +nodes.handlers = handlers + +local injections = nodes.injections or { } +nodes.injections = injections + +local traverse_nodes = node.traverse +local traverse_by_id = node.traverse_id +local count_nodes = nodes.count + +local nodecodes = nodes.nodecodes +local whatcodes = nodes.whatcodes +local skipcodes = nodes.skipcodes +local fillcodes = nodes.fillcodes + +local glyph_code = nodecodes.glyph +local hlist_code = nodecodes.hlist +local vlist_code = nodecodes.vlist +local disc_code = nodecodes.disc +local glue_code = nodecodes.glue +local kern_code = nodecodes.kern +local rule_code = nodecodes.rule +local whatsit_code = nodecodes.whatsit +local spec_code = nodecodes.glue_spec + +local localpar_code = whatcodes.localpar +local dir_code = whatcodes.dir + +local nodepool = nodes.pool + +local dimenfactors = number.dimenfactors +local formatters = string.formatters + +-- this will be reorganized: + +function nodes.showlist(head, message) + if message then + report_nodes(message) + end + for n in traverse_nodes(head) do + report_nodes(tostring(n)) + end +end + +function nodes.handlers.checkglyphs(head,message) + local t = { } + for g in traverse_by_id(glyph_code,head) do + t[#t+1] = formatters["%U:%s"](g.char,g.subtype) + end + if #t > 0 then + if message and message ~= "" then + report_nodes("%s, %s glyphs: % t",message,#t,t) + else + report_nodes("%s glyphs: % t",#t,t) + end + end + return false +end + +function nodes.handlers.checkforleaks(sparse) + local l = { } + local q = node.usedlist() + for p in traverse(q) do + local s = table.serialize(nodes.astable(p,sparse),nodecodes[p.id]) + l[s] = (l[s] or 0) + 1 + end + node.flush_list(q) + for k, v in next, l do + write_nl(formatters["%s * %s"](v,k)) + end +end + +local f_sequence = formatters["U+%04X:%s"] + +local function tosequence(start,stop,compact) + if start then + local t = { } + while start do + local id = start.id + if id == glyph_code then + local c = start.char + if compact then + if start.components then + t[#t+1] = tosequence(start.components,nil,compact) + else + t[#t+1] = utfchar(c) + end + else + t[#t+1] = f_sequence(c,utfchar(c)) + end + elseif id == whatsit_code and start.subtype == localpar_code or start.subtype == dir_code then + t[#t+1] = "[" .. start.dir .. "]" + elseif id == rule_code then + if compact then + t[#t+1] = "|" + else + t[#t+1] = nodecodes[id] + end + else + if compact then + t[#t+1] = "[]" + else + t[#t+1] = nodecodes[id] + end + end + if start == stop then + break + else + start = start.next + end + end + if compact then + return concat(t) + else + return concat(t," ") + end + else + return "[empty]" + end +end + +nodes.tosequence = tosequence + +function nodes.report(t,done) + report_nodes("output %a, %changed %a, %s nodes",status.output_active,done,count_nodes(t)) +end + +function nodes.packlist(head) + local t = { } + for n in traverse(head) do + t[#t+1] = tostring(n) + end + return t +end + +function nodes.idstostring(head,tail) + local t, last_id, last_n = { }, nil, 0 + for n in traverse_nodes(head,tail) do -- hm, does not stop at tail + local id = n.id + if not last_id then + last_id, last_n = id, 1 + elseif last_id == id then + last_n = last_n + 1 + else + if last_n > 1 then + t[#t+1] = formatters["[%s*%s]"](last_n,nodecodes[last_id] or "?") + else + t[#t+1] = formatters["[%s]"](nodecodes[last_id] or "?") + end + last_id, last_n = id, 1 + end + if n == tail then + break + end + end + if not last_id then + t[#t+1] = "no nodes" + elseif last_n > 1 then + t[#t+1] = formatters["[%s*%s]"](last_n,nodecodes[last_id] or "?") + else + t[#t+1] = formatters["[%s]"](nodecodes[last_id] or "?") + end + return concat(t," ") +end + +-- function nodes.xidstostring(head,tail) -- only for special tracing of backlinks +-- local n = head +-- while n.next do +-- n = n.next +-- end +-- local t, last_id, last_n = { }, nil, 0 +-- while n do +-- local id = n.id +-- if not last_id then +-- last_id, last_n = id, 1 +-- elseif last_id == id then +-- last_n = last_n + 1 +-- else +-- if last_n > 1 then +-- t[#t+1] = formatters["[%s*%s]"](last_n,nodecodes[last_id] or "?") +-- else +-- t[#t+1] = formatters["[%s]"](nodecodes[last_id] or "?") +-- end +-- last_id, last_n = id, 1 +-- end +-- if n == head then +-- break +-- end +-- n = n.prev +-- end +-- if not last_id then +-- t[#t+1] = "no nodes" +-- elseif last_n > 1 then +-- t[#t+1] = formatters["[%s*%s]"](last_n,nodecodes[last_id] or "?") +-- else +-- t[#t+1] = formatters["[%s]"](nodecodes[last_id] or "?") +-- end +-- return table.concat(table.reversed(t)," ") +-- end + +local function showsimplelist(h,depth,n) + while h do + write_nl(rep(" ",n) .. tostring(h)) + if not depth or n < depth then + local id = h.id + if id == hlist_code or id == vlist_code then + showsimplelist(h.list,depth,n+1) + end + end + h = h.next + end +end + +--~ \startluacode +--~ callback.register('buildpage_filter',function() nodes.show_simple_list(tex.lists.contrib_head) end) +--~ \stopluacode +--~ \vbox{b\footnote{n}a} +--~ \startluacode +--~ callback.register('buildpage_filter',nil) +--~ \stopluacode + +nodes.showsimplelist = function(h,depth) showsimplelist(h,depth,0) end + +local function listtoutf(h,joiner,textonly,last) + local joiner = (joiner == true and utfchar(0x200C)) or joiner -- zwnj + local w = { } + while h do + local id = h.id + if id == glyph_code then -- always true + w[#w+1] = utfchar(h.char) + if joiner then + w[#w+1] = joiner + end + elseif id == disc_code then + local pre, rep, pos = h.pre, h.replace, h.post + w[#w+1] = formatters["[%s|%s|%s]"] ( + pre and listtoutf(pre,joiner,textonly) or "", + rep and listtoutf(rep,joiner,textonly) or "", + mid and listtoutf(mid,joiner,textonly) or "" + ) + elseif textonly then + if id == glue_code and h.spec and h.spec.width > 0 then + w[#w+1] = " " + end + else + w[#w+1] = "[-]" + end + if h == last then + break + else + h = h.next + end + end + return concat(w) +end + +nodes.listtoutf = listtoutf + +local what = { [0] = "unknown", "line", "box", "indent", "row", "cell" } + +local function showboxes(n,symbol,depth) + depth, symbol = depth or 0, symbol or "." + for n in traverse_nodes(n) do + local id = n.id + if id == hlist_code or id == vlist_code then + local s = n.subtype + report_nodes(rep(symbol,depth) .. what[s] or s) + showboxes(n.list,symbol,depth+1) + end + end +end + +nodes.showboxes = showboxes + +local ptfactor = dimenfactors.pt +local bpfactor = dimenfactors.bp +local stripper = lpeg.patterns.stripzeros + +-- start redefinition +-- +-- -- if fmt then +-- -- return formatters[fmt](n*dimenfactors[unit],unit) +-- -- else +-- -- return match(formatters["%.20f"](n*dimenfactors[unit]),"(.-0?)0*$") .. unit +-- -- end +-- +-- redefined: + +local dimenfactors = number.dimenfactors + +local function numbertodimen(d,unit,fmt,strip) + if not d then + local str = formatters[fmt](0,unit) + return strip and lpegmatch(stripper,str) or str + end + local t = type(d) + if t == 'string' then + return d + end + if unit == true then + unit = "pt" + fmt = "%0.5f%s" + else + unit = unit or 'pt' + if not fmt then + fmt = "%s%s" + elseif fmt == true then + fmt = "%0.5f%s" + end + end + if t == "number" then + local str = formatters[fmt](d*dimenfactors[unit],unit) + return strip and lpegmatch(stripper,str) or str + end + local id = node.id + if id == kern_code then + local str = formatters[fmt](d.width*dimenfactors[unit],unit) + return strip and lpegmatch(stripper,str) or str + end + if id == glue_code then + d = d.spec + end + if not d or not d.id == spec_code then + local str = formatters[fmt](0,unit) + return strip and lpegmatch(stripper,str) or str + end + local width = d.width + local plus = d.stretch_order + local minus = d.shrink_order + local stretch = d.stretch + local shrink = d.shrink + if plus ~= 0 then + plus = " plus " .. stretch/65536 .. fillcodes[plus] + elseif stretch ~= 0 then + plus = formatters[fmt](stretch*dimenfactors[unit],unit) + plus = " plus " .. (strip and lpegmatch(stripper,plus) or plus) + else + plus = "" + end + if minus ~= 0 then + minus = " minus " .. shrink/65536 .. fillcodes[minus] + elseif shrink ~= 0 then + minus = formatters[fmt](shrink*dimenfactors[unit],unit) + minus = " minus " .. (strip and lpegmatch(stripper,minus) or minus) + else + minus = "" + end + local str = formatters[fmt](d.width*dimenfactors[unit],unit) + return (strip and lpegmatch(stripper,str) or str) .. plus .. minus +end + +number.todimen = numbertodimen + +function number.topoints (n,fmt) return numbertodimen(n,"pt",fmt) end +function number.toinches (n,fmt) return numbertodimen(n,"in",fmt) end +function number.tocentimeters (n,fmt) return numbertodimen(n,"cm",fmt) end +function number.tomillimeters (n,fmt) return numbertodimen(n,"mm",fmt) end +function number.toscaledpoints(n,fmt) return numbertodimen(n,"sp",fmt) end +function number.toscaledpoints(n) return n .. "sp" end +function number.tobasepoints (n,fmt) return numbertodimen(n,"bp",fmt) end +function number.topicas (n,fmt) return numbertodimen(n "pc",fmt) end +function number.todidots (n,fmt) return numbertodimen(n,"dd",fmt) end +function number.tociceros (n,fmt) return numbertodimen(n,"cc",fmt) end +function number.tonewdidots (n,fmt) return numbertodimen(n,"nd",fmt) end +function number.tonewciceros (n,fmt) return numbertodimen(n,"nc",fmt) end + +-- stop redefinition + +local points = function(n) + if not n or n == 0 then + return "0pt" + elseif type(n) == "number" then + return lpegmatch(stripper,format("%.5fpt",n*ptfactor)) -- faster than formatter + else + return numbertodimen(n,"pt",true,true) -- also deals with nodes + end +end + +local basepoints = function(n) + if not n or n == 0 then + return "0bp" + elseif type(n) == "number" then + return lpegmatch(stripper,format("%.5fbp",n*bpfactor)) -- faster than formatter + else + return numbertodimen(n,"bp",true,true) -- also deals with nodes + end +end + +local pts = function(n) + if not n or n == 0 then + return "0pt" + elseif type(n) == "number" then + return format("%.5fpt",n*ptfactor) -- faster than formatter + else + return numbertodimen(n,"pt",true) -- also deals with nodes + end +end + +local nopts = function(n) + if not n or n == 0 then + return "0" + else + return format("%.5f",n*ptfactor) -- faster than formatter + end +end + +number.points = points +number.basepoints = basepoints +number.pts = pts +number.nopts = nopts + +local colors = { } +tracers.colors = colors + +local unsetvalue = attributes.unsetvalue + +local a_color = attributes.private('color') +local a_colormodel = attributes.private('colormodel') +local m_color = attributes.list[a_color] or { } + +function colors.set(n,c,s) + local mc = m_color[c] + if not mc then + n[a_color] = unsetvalue + else + if not n[a_colormodel] then + n[a_colormodel] = s or 1 + end + n[a_color] = mc + end + return n +end + +function colors.setlist(n,c,s) + local f = n + while n do + local mc = m_color[c] + if not mc then + n[a_color] = unsetvalue + else + if not n[a_colormodel] then + n[a_colormodel] = s or 1 + end + n[a_color] = mc + end + n = n.next + end + return f +end + +function colors.reset(n) + n[a_color] = unsetvalue + return n +end + +-- maybe + +local transparencies = { } +tracers.transparencies = transparencies + +local a_transparency = attributes.private('transparency') +local m_transparency = attributes.list[a_transparency] or { } + +function transparencies.set(n,t) + local mt = m_transparency[t] + if not mt then + n[a_transparency] = unsetvalue + else + n[a_transparency] = mt + end + return n +end + +function transparencies.setlist(n,c,s) + local f = n + while n do + local mt = m_transparency[c] + if not mt then + n[a_transparency] = unsetvalue + else + n[a_transparency] = mt + end + n = n.next + end + return f +end + +function transparencies.reset(n) + n[a_transparency] = unsetvalue + return n +end + +-- for the moment here + +nodes.visualizers = { } + +function nodes.visualizers.handler(head) + return head, false +end |