1if not modules then modules = { } end modules ['attr-ini'] = {
2 version = 1.001,
3 comment = "companion to attr-ini.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 next, type = next, type
10local osexit = os.exit
11
12
16
17local nodes = nodes
18local context = context
19local storage = storage
20local commands = commands
21
22local implement = interfaces.implement
23
24attributes = attributes or { }
25local attributes = attributes
26
27local sharedstorage = storage.shared
28
29local texsetattribute = tex.setattribute
30
31attributes.names = attributes.names or { }
32attributes.numbers = attributes.numbers or { }
33attributes.list = attributes.list or { }
34attributes.states = attributes.states or { }
35attributes.handlers = attributes.handlers or { }
36attributes.unsetvalue = -0x7FFFFFFF
37
38local currentfont = font.current
39local currentattributes = nodes and nodes.currentattributes or node.currentattributes or node.current_attr
40
41local names = attributes.names
42local numbers = attributes.numbers
43local list = attributes.list
44
45storage.register("attributes/names", names, "attributes.names")
46storage.register("attributes/numbers", numbers, "attributes.numbers")
47storage.register("attributes/list", list, "attributes.list")
48
49
50
51
52
53
54
55
56
57
60
61names[0], numbers["fontdynamic"] = "fontdynamic", 0
62
63
68
69sharedstorage.attributes_last_private = sharedstorage.attributes_last_private or 15
70sharedstorage.attributes_last_public = sharedstorage.attributes_last_public or 1024
71
72function attributes.private(name)
73 local number = numbers[name]
74 if not number then
75 local last = sharedstorage.attributes_last_private
76 if last < 1023 then
77 last = last + 1
78 sharedstorage.attributes_last_private = last
79 else
80 report_attribute("no more room for private attributes")
81 osexit()
82 end
83 number = last
84 numbers[name], names[number], list[number] = number, name, { }
85 end
86 return number
87end
88
89function attributes.public(name)
90 local number = numbers[name]
91 if not number then
92 local last = sharedstorage.attributes_last_public
93 if last < 65535 then
94 last = last + 1
95 sharedstorage.attributes_last_public = last
96 else
97 report_attribute("no more room for public attributes")
98 osexit()
99 end
100 number = last
101 numbers[name], names[number], list[number] = number, name, { }
102 end
103 return number
104end
105
106attributes.system = attributes.private
107
108function attributes.define(name,category)
109 return (attributes[category or "public"] or attributes["public"])(name)
110end
111
112
113
114local report_attribute = logs.reporter("attributes")
115
116local function showlist(what,list)
117 if list then
118 local a = list.next
119 local i = 0
120 while a do
121 local number = a.number
122 local value = a.value
123 i = i + 1
124 report_attribute("%S %2i: attribute %3i, value %4i, name %a",what,i,number,value,names[number])
125 a = a.next
126 end
127 end
128end
129
130function attributes.showcurrent()
131 showlist("current",currentattributes())
132end
133
134function attributes.ofnode(n)
135 showlist(n,n.attr)
136end
137
138
139
140local store = { }
141
142function attributes.save(name)
143 name = name or ""
144 local n = currentattributes()
145 n = n and n.next
146 local t = { }
147 while n do
148 t[n.number] = n.value
149 n = n.next
150 end
151 store[name] = {
152 attr = t,
153 font = currentfont(),
154 }
155end
156
157function attributes.restore(name)
158 name = name or ""
159 local t = store[name]
160 if t then
161 local attr = t.attr
162 local font = t.font
163 if attr then
164 for k, v in next, attr do
165 texsetattribute(k,v)
166 end
167 end
168 if font then
169
170
171 currentfont(font)
172 end
173 end
174
175end
176
177implement {
178 name = "defineattribute",
179 arguments = "2 strings",
180 actions = { attributes.define, context }
181}
182
183
184
185implement {
186 name = "showattributes",
187 actions = attributes.showcurrent
188}
189
190implement {
191 name = "savecurrentattributes",
192 arguments = "string",
193 actions = attributes.save
194}
195
196implement {
197 name = "restorecurrentattributes",
198 arguments = "string",
199 actions = attributes.restore
200}
201 |