1if not modules then modules = { } end modules ['m-nodechart'] = {
2 version = 1.001,
3 comment = "companion to m-nodechart.mkiv",
4 author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
5 copyright = "PRAGMA ADE / ConTeXt Development Team",
6 license = "see context related readme files"
7}
8
9local format = string.format
10local points = number.nopts
11local ptfactor = number.dimenfactors.pt
12
13local nodecodes = nodes.nodecodes
14local kerncodes = nodes.kerncodes
15local penaltycodes = nodes.penaltycodes
16local gluecodes = nodes.gluecodes
17local whatsitcodes = nodes.whatsitcodes
18
19moduledata.charts = moduledata.charts or { }
20moduledata.charts.nodes = moduledata.charts.nodes or { }
21
22local formatters = { }
23
24
25
26function formatters.glyph(n,comment)
27 return format("\\doFLOWglyphnode{%s}{%s}{%s}{%s}{U+%05X}",comment,n.subtype,n.font,n.char,n.char)
28end
29
30
31
32function formatters.disc(n,comment)
33 return format("\\doFLOWdiscnode{%s}{%s}",comment,n.subtype)
34end
35
36
37
38function formatters.kern(n,comment)
39
40 return format("\\doFLOWkernnode{%s}{%s}{%.4f}",comment,kerncodes[n.subtype],n.kern*ptfactor)
41end
42
43
44
45function formatters.penalty(n,comment)
46 return format("\\doFLOWpenaltynode{%s}{%s}{%s}",comment,"penalty",n.penalty)
47end
48
49
50
51function formatters.glue(n,comment)
52 return format("\\doFLOWgluenode{%s}{%s}{%.4f}{%.4f}{%.4f}",comment,gluecodes[n.subtype],n.width*ptfactor,n.stretch*ptfactor,n.shrink*ptfactor)
53end
54
55
56
57function formatters.whatsit(n,comment)
58 return whatsitcodes[n.id] or "unknown whatsit"
59end
60
61function formatters.dir(n,comment)
62 return format("\\doFLOWdirnode{%s}{%s}{%s}",comment,"dir",n.dir)
63end
64
65function formatters.par(n,comment)
66 return format("\\doFLOWdirnode{%s}{%s}{%s}",comment,"par",n.dir)
67end
68
69
70
71local shapes = {
72 glyph = "procedure",
73 disc = "procedure",
74 kern = "action",
75 penalty = "action",
76 glue = "action",
77}
78
79local function flow_nodes_to_chart(specification)
80 local head = specification.head
81 local box = specification.box
82 local comment = specification.comment or ""
83 local x = specification.x or 1
84 local y = specification.y or 0
85
86 if box then
87 box = tex.getbox(tonumber(box))
88 head = box and box.list
89 end
90
91 local current = head
92
93 while current do
94 local nodecode = nodecodes[current.id]
95 local formatter = formatters[nodecode]
96 local shape = shapes[nodecode]
97 y = y + 1
98 local next = current.next
99 commands.flow_start_cell { shape = { framecolor = "nodechart:" .. nodecode } }
100 commands.flow_set_name(tostring(current))
101 commands.flow_set_location(x,y)
102 if shape then
103 commands.flow_set_shape(shape)
104 end
105 if formatter then
106 commands.flow_set_text("node",formatter(current,comment))
107 else
108 commands.flow_set_text("node",nodecode)
109 end
110 if next then
111 commands.flow_set_connection("bt","",tostring(next))
112 end
113 if nodecode == "glyph" then
114 local components = current.components
115 if components then
116 commands.flow_set_connection("rl","",tostring(components))
117 commands.flow_stop_cell()
118 n = flow_nodes_to_chart { head = components, comment = "component",x = x+2, y = y-1 }
119 else
120 commands.flow_stop_cell()
121 end
122 elseif nodecode == "disc" then
123 local pre = current.pre
124 local pos = current.post
125 local rep = current.replace
126 if pre and not rep and not rep then
127 if pre then
128 commands.flow_set_connection("rl","",tostring(pre))
129 end
130 commands.flow_stop_cell()
131 if pre then
132 n = flow_nodes_to_chart { head = pre, comment = "prebreak", x = x+1, y = y-1 }
133 end
134 else
135 if pre then
136 commands.flow_set_connection("rl","",tostring(pre))
137 end
138 if rep then
139 commands.flow_set_connection("+rl","",tostring(rep))
140 end
141 if pos then
142 commands.flow_set_connection("-rl","",tostring(pos))
143 end
144 commands.flow_stop_cell()
145 if pre then
146 n = flow_nodes_to_chart{ head = pre, comment = "prebreak", x = x+1, y = y-1 }
147 end
148 if rep then
149 n = flow_nodes_to_chart{ head = rep, comment = "replacement", x = x+3, y = y-1 }
150 end
151 if pos then
152 n = flow_nodes_to_chart{ head = pos, comment = "postbreak", x = x+2, y = y-1 }
153 end
154 end
155 elseif nodecode == "hlist" then
156 local list = current.list
157 if list then
158 commands.flow_set_connection("rl","",tostring(list))
159 commands.flow_stop_cell()
160 n = flow_nodes_to_chart { head = list, comment = "list", x = x+2, y = y-1 }
161 else
162 commands.flow_stop_cell()
163 end
164 else
165 commands.flow_stop_cell()
166 end
167 current = next
168 end
169end
170
171function moduledata.charts.nodes.chart(specification)
172 commands.flow_start_chart(specification.name)
173 flow_nodes_to_chart(specification)
174 commands.flow_stop_chart()
175end
176 |