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