1if not modules then modules = { } end modules ['attr-eff'] = {
2 version = 1.001,
3 comment = "companion to attr-eff.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 attributes, nodes, backends, utilities = attributes, nodes, backends, utilities
10local tex = tex
11
12local states = attributes.states
13local enableaction = nodes.tasks.enableaction
14local nodeinjections = backends.nodeinjections
15local texsetattribute = tex.setattribute
16local allocate = utilities.storage.allocate
17local setmetatableindex = table.setmetatableindex
18local formatters = string.formatters
19
20local interfaces = interfaces
21local implement = interfaces.implement
22
23local v_normal <const> = interfaces.variables.normal
24
25attributes.effects = attributes.effects or { }
26local effects = attributes.effects
27
28local a_effect <const> = attributes.private('effect')
29
30effects.data = allocate()
31effects.values = effects.values or { }
32effects.registered = effects.registered or { }
33effects.attribute = a_effect
34
35local data = effects.data
36local registered = effects.registered
37local values = effects.values
38
39local f_stamp = formatters["%s:%s:%s"]
40
41storage.register("attributes/effects/registered", registered, "attributes.effects.registered")
42storage.register("attributes/effects/values", values, "attributes.effects.values")
43
44
45
46local function effect(...) effect = nodeinjections.effect return effect(...) end
47
48local function extender(effects,key)
49 if key == "none" then
50 local d = effect(0,0,0)
51 effects.none = d
52 return d
53 end
54end
55
56local function reviver(data,n)
57 local e = values[n]
58 local d = effect(e[1],e[2],e[3])
59 data[n] = d
60 return d
61end
62
63setmetatableindex(effects, extender)
64setmetatableindex(effects.data, reviver)
65
66effects.handler = nodes.installattributehandler {
67 name = "effect",
68 namespace = effects,
69 initializer = states.initialize,
70 finalizer = states.finalize,
71 processor = states.process,
72}
73
74local function register(specification)
75 local alternative, stretch, rulethickness
76 if specification then
77 alternative = specification.alternative or v_normal
78 stretch = specification.stretch or 0
79 rulethickness = specification.rulethickness or 0
80 else
81 alternative = v_normal
82 stretch = 0
83 rulethickness = 0
84 end
85 local stamp = f_stamp(alternative,stretch,rulethickness)
86 local n = registered[stamp]
87 if not n then
88 n = #values + 1
89 values[n] = { alternative, stretch, rulethickness }
90 registered[stamp] = n
91 end
92 return n
93end
94
95local enabled = false
96
97local function enable()
98 if not enabled then
99 enableaction("shipouts","attributes.effects.handler")
100 enabled = true
101 end
102end
103
104effects.register = register
105effects.enable = enable
106
107
108
109implement {
110 name = "seteffect",
111 actions = function(specification)
112 if not enabled then
113 enable()
114 end
115 texsetattribute(a_effect,register(specification))
116 end,
117 arguments = {
118 {
119 { "alternative", "string" },
120 { "stretch", "integer" },
121 { "rulethickness", "dimen" }
122 }
123 }
124}
125
126implement {
127 name = "reseteffect",
128 actions = function()
129 if enabled then
130 texsetattribute(a_effect,register())
131 end
132 end
133}
134 |